Dave Herman
ES6 Deep Dive
Symbols, Structs, Generators
Slide 2
Slide 2 text
No content
Slide 3
Slide 3 text
About me
• @littlecalculist
• http://calculist.org
• http://github.com/dherman
• Mozilla Research
• TC39
• Also…
Slide 4
Slide 4 text
In print this December
http://effectivejs.com
Slide 5
Slide 5 text
Symbols
Slide 6
Slide 6 text
JS property names are strings
var obj = { foo: 42 };
obj["foo"]; // 42
Slide 7
Slide 7 text
The all-powerful _ character
function Dict() {
this._entries = {};
}
Don’t touch me,
I’m private!
Slide 8
Slide 8 text
When you mean business…
__proto__
private SO PRIVATE
REALLY GUYS
SOOO TOTALLY
PRIVATE
private!
Slide 9
Slide 9 text
Conventions are no guarantee
function SuperClass() {
this._data = "superclass private data";
}
function SubClass() {
SuperClass.call(this);
this._data = "subclass private data"; // collision!
}
SubClass.prototype = Object.create(SuperClass.prototype);
Slide 10
Slide 10 text
Closures for information hiding
function SuperClass() {
var data = "private data";
this.method = function() {
/* ... */ data /* ... */
};
}
no sharing: one
method per
instance!
Slide 11
Slide 11 text
Introducing symbols
Slide 12
Slide 12 text
Introducing symbols
var sym = new Symbol("data");
Slide 13
Slide 13 text
Introducing symbols
var sym = new Symbol("data");
function SuperClass() {
this[sym] = "private data";
}
Slide 14
Slide 14 text
Introducing symbols
var sym = new Symbol("data");
function SuperClass() {
this[sym] = "private data";
}
SuperClass.prototype.method = function() {
/* ... */ this[sym] /* ... */
};
Slide 15
Slide 15 text
Introducing symbols
var obj = new SuperClass();
"data" in obj; // false
"_data" in obj; // false
sym in obj; // true
Slide 16
Slide 16 text
Performance
• Engines already do string interning
• Convertible to a fixed offset with inline caches
Download three files
var files = [];
["foo", "bar", "baz"].forEach(function(url, i) {
load(url, function(file) {
files.push(file); // no!
if (i === 3) // no!
use(files);
});
});
Slide 30
Slide 30 text
Download three files
var files = [];
["foo", "bar", "baz"].forEach(function(url, i) {
load(url, function(file) {
files[i] = file;
if (files.length === 3) // still no!
use(files);
});
});
Slide 31
Slide 31 text
Download three files
var files = [], count = 0;
["foo", "bar", "baz"].forEach(function(url, i) {
load(url, function(file) {
files[i] = file;
if (++count === 3)
use(files);
});
});
Slide 32
Slide 32 text
JavaScript is concurrent
Cooperative concurrency: easier, but not easy!
Handlers run sequentially but start concurrently.
Shared state 㱺 race conditions 㱺 pain and suffering
task.js: Beautiful concurrency
spawn(function*() {
var files = yield join(load("foo"), load("bar"), load("baz"));
use(files);
});
create a task that
can be paused
pause!
http://taskjs.org
Slide 35
Slide 35 text
Generator functions
function* evenNumbers() {
for (var next = 0; true; next += 2) {
yield next;
}
}
Slide 36
Slide 36 text
Generator functions
function* evenNumbers() {
for (var next = 0; true; next += 2) {
yield next;
}
}
Slide 37
Slide 37 text
Generator functions
function* evenNumbers() {
for (var next = 0; true; next += 2) {
yield next;
}
}
evenNumbers();
✗
Slide 38
Slide 38 text
Generator functions
function* evenNumbers() {
for (var next = 0; true; next += 2) {
yield next;
}
}
evenNumbers();
✗
Slide 39
Slide 39 text
Generators
function* f() {
}
Slide 40
Slide 40 text
Generators
function* f() {
}
.next:
var g = f();
⋮
Slide 41
Slide 41 text
Generators
function* evenNumbers() { /* ... */ }
var g = evenNumbers();
g.next(); // 0
g.next(); // 2
g.next(); // 4
starts out paused
Slide 42
Slide 42 text
Lazy iteration
Dict.prototype.keys = function*() {
for (var key in this._entries)
yield key;
};
Slide 43
Slide 43 text
Iterators work with for-of
var dict = new Dict();
// ...
for (var key of dict.keys()) {
console.log(key + ": " + dict.get(key));
}