From November 27-29, 2012, the Ecma Technical Committee 39 (TC39,
[1]) had another meeting, where decisions were made about ECMAScript.next (the code name for ECMAScript 6
[1]). This blog post summarizes and explains the highlights. It is based on Rick Waldrons
excellent notes that he put up on GitHub. There is also
a list of all 2ality posts on TC39 meetings.
November 27
November 28
Symbols
Among other things, symbols are used for private properties in ECMAScript 6
[4]. A proposal for adding special syntactic support for them has been rejected, you’ll have to create them “manually”:
let _id = new PrivateSymbol();
let _log = new PrivateSymbol();
However, computed property keys have been revived and will be part of ECMAScript.next.
Currently we only have static property keys. In ECMAScript.next, you’ll also be able to write an expression in square brackets and its result will be used as the key. For example:
let logger = {
[_id]: "ID2543",
[_log](message) {
console.log(this[_id]+": "+message);
}
};
You can only access the two properties above if you know the values in
_id and
_log. They can’t be listed via the usual means (
Object.getOwnPropertyNames(), for-in, etc.), either. Computed keys also work in ECMAScript 6 classes
[5]:
class LoggerFactory {
constructor(id) {
this[_id] = id;
}
[_log](message) {
console.log(this[_id]+": "+message);
}
}
The advantage of this approach is that it gives you a lot of freedom, because you can explicitly control who has access to a symbol. The disadvantage is that every private identifier has to be declared in advance, leading to redundancy. TC39 does not rule out adding syntax after ECMAScript 6 to reduce some of that work.
Modules
The design of modules is work in progress. The following snippets demonstrate current ideas.
Defining a nested module:
module "foo" {
module "bar" {
// ...
}
}
// Equivalent:
module "foo/bar" {
// ...
}
Importing a nested module:
import "foo/bar" as m;
November 29
Chaining calls to collections
The following methods will return
this:
- Map.prototype.set
- WeakMap.prototype.set
- Set.prototype.add
That allows one to chain them. For example:
let s = new Set();
s.add('foo').add('bar');
Or even:
let s = new Set().add('foo').add('bar');
Iterating over objects
ECMAScript 6 will have an iteration protocol
[3]. An object adheres to that protocol by providing a method whose key is the well-known symbol @@iterator. The method returns an iterator over the “elements” of the object.
An object that implements the iteration protocol is called
iterable. Arrays and the Array-like
arguments object will be iterable. Iteration operations use the iteration protocol as follows:
- Array.from converts iterable and Array-like objects to arrays. If the iteration protocol is supported, it uses it. Otherwise, the object is considered Array-like and converted accordingly.
- for-of loop [3]: only supports iteration protocol.
- Spread (...) operator: only supports iteration protocol. This operator allows one to insert the elements of an array into a function call or an array literal. Examples:
myFunc(a, b, ...myArray, c)
[a, b, ...myArray, c]
Among other things, spread can often be used instead of apply().
Collection APIs
The collection types
Array,
Map,
WeakMap and
Set will have the following three methods that return iterables (not iterators!):
- keys(): returns an iterable of the keys of the collection.
- values(): returns an iterable of the values of the collection.
- entries(): returns an iterable of two-element [key,value] arrays.
There will be functions (importable from a module) that perform the same operation for objects. That is, objects will not be iterable. The rationale for that is to keep iterating of the content of an object such as a collection separate from iterating over the properties of an object.
let declarations in non-strict code
let is only a keyword in strict mode (ECMA-262, Sect.
7.6.1.2). Thus, the following code is legal in non-strict mode.
var let;
let[x] = 5;
The second line could be mistaken for a let declaration, because ECMAScript.next will have destructuring assignment. For example:
[x, y] = [y, x];
let [a, b] = computePair();
let [c] = computeSingleElementArray();
The following rules will be used for parsing
let:
let at the beginning of a statement is a let declaration, but it must be followed by either an identifier, an opening square brace "[" or an opening curly brace "{".
This rule does not prevent the above mentioned problem in old code, but TC39 will try and inform people about it, so that hopefully nothing important breaks once this feature appears in browsers. However, the rule does prevent all other problems with using
let as a variable name.
Array comprehensions and generator comprehensions: two new clauses
As explained in
[6], there can be four kinds of clauses in comprehensions:
for,
if,
let,
const. The last two are new.
References
- ECMAScript: ES.next versus ES 6 versus ES Harmony [also explains what TC39 is]
- Jed – a JavaScript internationalization toolkit
- ECMAScript.next: for-of, iterators, generators
- Private data for objects in JavaScript
- ECMAScript.next: classes
- ECMAScript.next: array comprehensions and generator comprehensions