Tags:

Using an object literal populated with some member functions is a common practice in any serious JavaScript applications. This is also useful for all kind of frameworks, in particular to setup object prototypes. The upcoming ECMAScript 6 introduces method definition, a nice shorthand which eliminates the need to use function when using that pattern.

Before we see method definition in action, let us have a quick refresh on property setter and getter. This is part of the current ECMAScript 5.1, see Section 11.1.5 on Object Initialiser. The idea is to use set and get to bind an object property to a function which will be invoked when that property is set and looked up, respectively. The following code fragment demonstrates its usage:

var BigLoco = {
  locoName: 'Gordon',
  get name() { return this.locoName; },
  set name(n) { this.locoName = n }
};
 
console.log(BigLoco.name); // 'Gordon'

Practically, we have a way to define a function without using the function keyword. With ECMAScript 6, this is extended further so that the syntax applies not only to property getter and setter, but also to plain functions. This is called Method Definitions, see Section 13.3 in the latest ES6 draft.

Take a look at an example ECMAScript 6 code here, in particular to the start and stop functions.

var SteamEngine = {
  color: 'blue',
  get name() { return 'Thomas' },
  start() { console.log('Hurry up!'); },
  stop() { console.log('Screech...! That was close.'); }
};
 
console.log('My name is', SteamEngine.name);
SteamEngine.start();
SteamEngine.stop();

If we were about to transpile the code to ES5, the construct will look like:

var SteamEngine = {
  color: 'blue',
  get name() { return 'Thomas' },
  start: function() { console.log('Hurry up!'); },
  stop: function() { console.log('Screech...! That was close.'); }
};

The ECMAScript 6 version shows a nice symmetry thanks to this syntactic sugar. Every property on that literal looks the same and it’s not really difficult to spot the functions due to the necessary parentheses. Sweet!

Tags:

To have a silky smooth experience on mobile web, it is important to gather relevant performance data so that a suitable optimization can be carried out. Traditionally, such a measurement activity is full of (black) magic since the web browser itself often does not expose enough performance metrics. These days, the situation is much better since browser vendors start to hook various types of instrumentation. The latest Chrome 25 for Android can even display a very useful frame rate HUD to gauge the rendering performance.

Using Chrome’s FPS Counter requires a very simple initial step: going to the special URL chrome://flags and enabling that particular option (note that this is also the exact same setup for Chrome for desktop). In many cases, it is also useful to enable Composited render layer borders. With these debugging borders, you will be able to see which DOM element is mapped into a GPU texture for the hardware-accelerated compositing. For some info on the machinery of GPU compositing, check out the video (and the slide deck) of my recent W3Conf talk.

framerate

After a relaunch, pay attention to the top right corner. This is where Chrome (more precisely, its Compositor module) displays some essential metrics in a simple head-up display (HUD):

  • Actual frame rate (average, minimum, maximum)
  • Frame rate chart (as a function of time)
  • Frame rate histogram
  • GPU memory status

The last information is quite useful. Like what I mentioned in my W3Conf talk, GPU memory should be treated as a cache. Simply doing a blind translate3d on every single element will be quite harmful because you will quickly fill that memory (overbudget). Having this memory statistics, combined with the actual frame rate rendered by Chrome, means that front-end developers won’t be flying blind anymore when it gets to rendering performance analysis and optimization.

To the glory of 60 fps!

Tags:

We have seen how a rest parameter can help the handling of a variable number of function arguments. What about the other way around? Can we turn an array into a series of function arguments? Apparently, ECMAScript 6 defines a new type of operator called the spread operator which does exactly that.

Let us review again our previous example with a supplier truck and a grocery store. Assuming the API of the store accepts a variable number of items for a particular category:

store.add('fruit', 'apple');
store.add('dairy', 'milk', 'cheese', 'yoghurt');
store.add('pastries', 'donuts', 'croissants');

We assume that these delicious items are stored in some boxes, each box happens to be an array:

var dairyBox = ['milk', 'cheese', 'yoghurt'];

A possible solution (out of many others) to invoke store’s add function with the items in the above array is by using Function.prototype.apply. Since we need to pass the food category as the first argument, a little bit dancing with Array.concat is necessary:

store.add.apply(store, ['dairy'].concat(dairyBox));

For the untrained eyes, it looks like one of those magical JavaScript incantations.

With ECMAScript 6, this can be simplified by using ... prefix in a spread expression (section 11.2.5, ES6 draft Rev 14).

store.add('dairy', ...dairyBox);

That dairyBox array is simply spread to fill the remaining argument list.

spreadexpression

Obviously, one possibly common place where spreading is always useful is when dealing with arrays. We know that push accepts multiple number of arguments. The implementation of add function originally looks like:

store.add = function(category, ...items) {
  items.forEach(function (item) {
    store.aisle[category].push(item);
  });
};

which can be further shortened to become something like the following fragment. Nifty, isn’t it?

store.add = function(category, ...items) {
  store.aisle[category].push(...items);
};

(This is of course unnecessary if you choose to change the API to simply accept a single array for the items, instead of a rest parameter combined with spreading).

The use of a spread operator can lead to a different way of combining arrays:

var x = [1, 2];
var y = [3, 4];
x.push(...y);  // x is [1, 2, 3, 4]

What other tricks do you have in mind once you have the spread operator ready to abuse?

Tags:

Code autocomplete is probably one of the exciting features of a programmer’s text editor. Ever since Eclipse Orion started to demonstrate its wonderful Content Assist feature last summer, I do believe that an online, web-based editing component should always provide a minimalistic and convenient autocompletion. Fortunately, this is rather easy to achieve these days, thanks to Orion and Scripted.

With the recent growing interests to improve the state of JavaScript language tooling, I thought it is a good time to publish a simple example that I have put together some time ago. The editor itself is the same one used in Eclipse Orion. With its recent version 2.0 release, it becomes rather easy to embed Orion editor in any web page: one JavaScript file, one CSS file, and a bit of of glue code.

jsautocomplete

For the autocompletion itself, Scripted’s Content Assist is employed. As I have written before, it has a well-developed type inferencer. Using a simple static code analysis, it can detect the possible matches on a best-effort basis. In addition to that, JSDoc-style of type annotation is also supported.

You can enjoy the working example at esprima.org/demo/autocomplete.html. Have fun!

Tags:

Handling a function with a variable number of arguments is always tricky in JavaScript. At least, we still have this arguments object which can be used to retrieve all arguments used to invoke a function. With the upcoming ECMAScript 6, no such hack is necessary anymore since we can start using its rest parameter feature.

To see how a rest parameter works, consider the following scenario. You drive a truck which delivers some supplies to a grocery store. As you unload the supplies, you add them to the store:

store.add('fruit', 'apple');
store.add('dairy', 'milk', 'cheese', 'yoghurt');
store.add('pastries', 'donuts', 'croissants');

whereby add is implemented as something like:

store.add = function(category) {
  var items = [].slice.call(arguments, 1);
  items.forEach(function (item) {
    store.aisle[category].push(item);
  });
};

Note how arguments object can’t be treated as a normal array, although it behaves almost like an array. A well-known trick with Array.prototype.slice and Function.prototype.call is the workaround, giving us the list of all arguments which comes after the first one (category).

With a rest parameter (Section 13.1, ES 6 draft Rev 13), the implementation is much simpler. It is even self-explanatory.

store.add = function(category, ...items) {
  items.forEach(function (item) {
    store.aisle[category].push(item);
  });
};

Another typical use-case where a rest parameter could be useful is a pubsub-like pattern. If you write a Backbone.js-based application, triggering an event via Backbone.Event.trigger is a common practice. Because an event may require one or more parameters, the implementation of the trigger function itself looks like:

trigger: function(name) {
    if (!this._events) return this;
    var args = slice.call(arguments, 1);
    /// ... do something with args ...
    return this;
},

for which I’m sure you can come up with a slightly different look if you have the rest parameter feature as your disposal!

Obviously we don’t need a rest parameter if we switch the API to accept an array as the second argument. However, in some cases, it would feel less natural. For example, a string formatter implementation is expected to follow the de-facto printf format string rather than grouping every parameters in a simple array.

Just like other syntactic sugar in ECMAScript 6, a rest parameter does not radically change you write your JavaScript code. It does however make the code more tool-friendly, shifting the semantic interpretation of the code from the run-time behavior into something at the syntax level. Once editors and IDEs understand the construct, a simple code hint which reveals the function signature is more than enough to indicate that the said function accepts a variable number of arguments.

Isn’t it exciting?

Tags:

Constructing an object using the literal syntax is something that is very familiar to every JavaScript developer, quite likely because this reminds everyone of JSON. While every object property needs to be either a key-value pair or getter/setter, this may change in the near future. Another syntactic sugar in the upcoming ECMAScript 6 is the object literal property value shorthand.

Consider the following ECMAScript 5 fragment:

function createMonster(name, power) {
  return { type: 'Monster', name: name, power: power };
}
function createWitch(name) {
  return { type: 'Witch', name: name };
}

With the new shorthand form, this can be rewritten as the following code:

function createMonster(name, power) {
  return { type: 'Monster', name, power };
}
function createWitch(name) {
  return { type: 'Witch', name };
}

As you can see, this works because the property value has the same name as the property identifier. This a new addition to the syntax of Object Initialiser (section 11.1.5) in the latest ECMAScript 6 draft Rev 13. Of course, just like the limitations set from ECMAScript 3, you can’t use a reserved word as your property name.

What about real-world code which can use the shorthand notation? Somewhere in Backbone.js, we should be able to use the following form instead of its longer one:

route: function(route, callback) {
  this.handlers.unshift({route, callback});
},

For improved readibility, many times we use temporary variables before constructing an object out of the properties. As another example, a piece of code QUnit may have the following simplified syntax:

test = new Test({nameHtml, testName, expected, async,
  callback,module: config.currentModule,
  moduleTestEnvironment: config.currentModuleTestEnvironment,
  stack: sourceFromStacktrace(2)
});

Such a shorthand won’t dramatically change your code, it only makes everything a little bit sweeter!

Addendum. While the literal shorthand is useful on its own, in many cases it would be more frequently encountered as it is combined with object pattern (see my previous post on ECMAScript 6 destructuring). Thus, the following code fragment:

books.forEach(function ({title: title, author: author}) {
  console.log(title, 'is written by', author);
});

turns into something like this one:

books.forEach(function ({title, author}) {
  console.log(title, 'is written by', author);
});

As you can see, such a symmetry is well suited for this case.