The software team at Factual relies heavily on the outstanding work of the open source software community, and we’re always looking for opportunities to return the favor by donating our engineering time and effort.

JS2 is the first of hopefully many internal projects that we’re releasing as free, open source software. Our wish is that others will find JS2 either directly useful in their future projects, or indirectly helpful via idea exchange.

[Note: what follows is pretty technical. But if Javascript syntax doesn't intimidate you, read on.]

Factual’s grid consists of about 4 man-years of Javascript. Before developing the grid, we wanted to adopt familiar object-oriented methodologies in our Javascript. Although its flexible, Javascript doesn’t support much in the way of object-oriented programming. Fortunately, there is no shortage of great frameworks (Prototype, YUI, etc…) out there that solve this problem in Javascript’s runtime environment. While this methodology works, we found the syntax can be somewhat unfamiliar to our developers.

Our in-house solution was to develop a compiler that would convert object-oriented Javascript syntax into cross-browser compatible Javascript. This solution allows Javascript developers to take more control of their architecture by using a more familiar syntax.

Some features include:

  • inheritance
  • mixins (Ruby’s answer to multiple inheritance)
  • syntactic sugar
    • “foreach” iterators
    • currying
    • getters/setters
  • haml template assets
  • compiler can be run in a daemon mode so that it “watches” for changed files

Installation:

  • Install ruby gems. http://docs.rubygems.org/
  • Install js2 gem by running something like: sudo gem install js2
  • Follow the example below

A JS2 Example (do this in a new directory):

Create a file called example.js2:

class Shape { 
  // creates getters and setters 
  // getX() or setX(n)
  property x, y;
  function position (x, y) {
    this.setX(x);
    this.setY(y);
  }
}
 
// a ruby-like module that provides both
// interface and implementation
module Rectangular { 
  property width, height;
 
  function getArea () {
    return this.getWidth() * this.getHeight();
  }
}
 
// inherits Shape
class Rectangle extends Shape {
  // adds: getArea, getWidth, setWidth, etc... 
  // by extending Shape
  include Rectangular; 
}
 
class Square extends Rectangle {
 
  // enforce data integrity by overriding
  // setHeight and setWidth
  function setHeight (n) {
    this.height = n;
    this.width  = n;
  }
 
  function setWidth (n) {
    this.height = n;
    this.width  = n;
  }
}
 
var square = new Square();
square.setWidth(20);
alert(square.getArea());

Now run:

js2 .

There will now be 3 files in this directory: example.js2, example.js, js2bootstrap.js

Just include js2bootstrap.js and example.js (in that order) in the “head” section of your html file and it should run the code. Go ahead and peek inside example.js to see what the js2 code is converted to.

We will transition JS2 to a public repository soon. More information can be found at http://code.google.com/p/js2lang

We hope you enjoy and benefit from our open source labors. And of course, we welcome your feedback!

– Jeff Su, Engineer at Factual