My favorites | Sign in
Project Home Source
Search
for
LanguageFeatures  
Traceur Language Features
Featured
Updated Mar 26, 2013 by arv@chromium.org

Language Features

Property Method Assignment

These features are proposals for ECMAScript Harmony unless otherwise noted.

Classes

This implements class syntax and semantics as described in the ES6 draft spec. In earlier versions of Traceur we had more feature rich classes but in the spirit of Harmony we have scaled back and are now only supporting the minimal class proposal.

Classes are a great way to reuse code. Several JS libraries provide classes and inheritance, but they aren't mutually compatible. Here's an example:

class Monster extends Character {
  constructor(x, y, name) {
    super(x, y);
    this.name = name;
    this.health_ = 100;
  }

  attack(character) {
    super.attack(character);
  }

  get isAlive() { return this.health > 0; }
  get health() { return this.health_; }
  set health(value) {
    if (value < 0) throw new Error('Health must be non-negative.');
    this.health_ = value;
  }
}

Here's an example of subclassing an HTML button:

class CustomButton extends HTMLButtonElement {
  constructor() {
    this.value = 'Custom Button';
  }
  // ... other methods ...
}
var button = new CustomButton();
document.body.appendChild(button);

Warning This is currently not supported.

Modules

Modules are not ready to use yet in Traceur, but they are partially implemented. Modules try to solve many issues in dependencies and deployment, allowing users to name external modules, import specific exported names from those modules, and keep these names separate.

module Profile {
  // module code
  export var firstName = 'David';
  export var lastName = 'Belle';
  export var year = 1973;
}

module ProfileView {
  import Profile.{firstName, lastName, year};

  function setHeader(element) {
    element.textContent = firstName + ' ' + lastName;
  }
  // rest of module
}

Iterators and For Of Loops

Iterators are objects that can traverse a container. It's a useful way to make a class work inside a for of loop. The interface is similar to the iterators proposal. Iterating with a for of loop looks like:

for (let element of [1, 2, 3]) {
  console.log(element);
}

You can also create your own iterable objects. Normally this is done via the yield keyword (discussed below in Generators) but it could be done explicitly by returning an object that has __iterator__:

function iterateElements(array) {
  return {
    __iterator__: function() {
      var index = 0;
      var current;
      return {
        get current() {
          return current;
        },
        moveNext: function() {
          if (index < array.length) {
            current = array[index++];
            return true;
          }
          return false;
        }
      };
    }
  };
}

Generators

Generators make it easy to create iterators. Instead of tracking state yourself and implementing __iterator__, you just use yield (or yield* to yield each element in an iterator):

// A binary tree class.
function Tree(left, label, right) {
  this.left = left;
  this.label = label;
  this.right = right;
}
// A recursive generator that iterates the Tree labels in-order.
function* inorder(t) {
  if (t) {
    yield* inorder(t.left);
    yield t.label;
    yield* inorder(t.right);
  }
}

// Make a tree
function make(array) {
  // Leaf node:
  if (array.length == 1) return new Tree(null, array[0], null);
  return new Tree(make(array[0]), array[1], make(array[2]));
}
let tree = make([[['a'], 'b', ['c']], 'd', [['e'], 'f', ['g']]]);

// Iterate over it
for (let node of inorder(tree)) {
  console.log(node); // a, b, c, d, ...
}

A generator function needs to be anotated as function* instead of just function.

Deferred Functions

Deferred functions allow you to write asynchronous non-blocking code without writing callback functions, which don't compose well. With deferred functions, you can use JavaScript control flow constructs that you're used to, inline with the rest of your code.

function deferredAnimate(element) {
    for (var i = 0; i < 100; ++i) {
        element.style.left = i;
        await deferredTimeout(20);
    }
};

deferredAnimate(document.getElementById('box'));

Deferred functions use await expressions to suspend execution and return an object that represents the continuation of the function.

Block Scoped Bindings

Block scoped bindings provide scopes other than the function and top level scope. This ensures your variables don't leak out of the scope they're defined:

{
  const tmp = a;
  a = b;
  b = tmp;
}
alert(tmp); // error: 'tmp' is not defined.

It's also useful for capturing variables in a loop:

let funcs = [];
for (let i of [4,5,6]) {
  funcs.push(function() { return i; });
}
for (var func of funcs) {
  console.log(func()); // 4, 5, 6
}

Destructuring Assignment

Destructuring assignment is a nice way to assign or initialize several variables at once:

var [a, [b], c, d] = ['hello', [', ', 'junk'], ['world']];
alert(a + b + c); // hello, world

It can also destructure objects:

var pt = {x: 123, y: 444};
var rect = {topLeft: {x: 1, y: 2}, bottomRight: {x: 3, y: 4}};
// ... other code ...
var {x, y} = pt; // unpack the point
var {topLeft: {x: x1, y: y1}, bottomRight: {x: x2, y: y2}} = rect;

alert(x + y); // 567
alert([x1, y1, x2, y2].join(',')) // 1,2,3,4

Default Parameters

default parameters allow your functions to have optional arguments without needing to check arguments.length or check for undefined.

function slice(list, indexA = 0, indexB = list.length) {
  // ... 
}

Rest Parameters

Rest parameters allows your functions to have variable number of arguments without using the arguments object.

function push(array, ...items) {
  items.forEach(function(item) {
    array.push(item);
  });
}

The rest parameter is an instance of Array so all the array methods just works.

Spread Operator

The spread operator is like the reverse of rest parameters. It allows you to expand an array into multiple formal parameters.

function push(array, ...items) {
  array.push(...items);
}

function add(x, y) {
  return x + y;
}

var numbers = [4, 38];
add(...numbers);  // 42

The spread operator also works in array literals which allows you to combine multiple arrays more easily.

var a = [1];
var b = [2, 3, 4];
var c = [6, 7];
var d = [0, ...a, ...b, 5, ...c];

Object Initialiser Shorthand

This proposal allows you to skip repeating yourself when the property name and property value are the same in an object literal.

function getPoint() {
  var x = ...;
  var y = ...;
  ...
  return {x, y};
}

Property Method Assignment

Did you ever end up staring at code looking like this wondering where the syntax error was?

var object = {
  value: 42,
  toString() {
    return this.value;
  }
};

This proposal makes this a valid way to define methods on objects. The methods are non enumerable so that they behave like the methods on the built in objects.

Comment by danielcr...@gmail.com, May 6, 2011

The example for classes doesn't work. Looking at the tests in trunk the syntax appears to be: class Monster : Character { }

The online Repl currently doesn't support either syntax.

Comment by project member arv@google.com, May 9, 2011

@daniel: I updated the example and fixed a bug that this example exposes. You need to use http://code.google.com/p/traceur-compiler/source/detail?r=287 or later. Note, that the sample depends on the class Character which is not in that example.

Comment by e...@carbonfive.com, Nov 21, 2013

Generators example isn't functioning (in the provided REPL: http://traceur-compiler.googlecode.com/git/demo/repl.html):

"unexpected token let"

When replacing the let-keyword with var, the REPL shows a simple "undefined."

Compiling locally and running in a browser, I see:

"$traceurRuntime is not defined" from the compiled JavaScript?.

Comment by baran...@gmail.com, Jun 21, 2014

Thanks this is help me to develop application

http://www.walldc.com/romantic-photos-wallpapers/

Comment by jgras...@gmail.com, Aug 26 (6 days ago)

I'm wondering about the public/private modifiers for variables. Are those supported? I get errors when trying to use them


Sign in to add a comment
Powered by Google Project Hosting