ECMAScript 2015 Tips & Traps
-
Upload
adrian-tudor-panescu -
Category
Software
-
view
285 -
download
0
Transcript of ECMAScript 2015 Tips & Traps
ECMAScript 2015Tips & Traps
Adrian-Tudor Panescu
Iasi, November 2015
5
What’s all about?
● 500+ new features● Backwards-compatible● A much-awaited update (~6 years)● Hopefully the step to a yearly release cycle
6
ES6 or ES2015?
https://twitter.com/JavaScriptDaily/status/662020174837583872
7
Where are we?
Source: https://kangax.github.io/compat-table/es6/05.11.2015
8
Where are we?
https://twitter.com/JavaScriptDaily/status/660074434821246976
10
Where am I?
● Using ES2015 in production for ~year● 2nd presentation on ES2015 at CodeCamp● Reported Babel and ESLint bugs:
○ https://github.com/babel/babel/issues/2743○ https://github.com/eslint/eslint/issues/3364○ https://github.com/eslint/eslint/issues/3510
11
Tip: arrow functions and this
function Ping() {
this.count = 1;
setInterval(function() {
this.count += 1;
}.bind(this), 16.6);
}
function Ping() {
this.count = 1;
setInterval(() => {
this.count += 1;
}, 16.6);
}
12
Trap: arrow functions and arguments
function foo() {
console.log(arguments);
}
foo(1); // [1]
var foo = () => {
console.log(arguments);
}
foo(1); // ReferenceError
13
Trap: arrow functions and arguments
● Use rest parameters: (...args) => args● Babel uses arguments from enclosing scope (?)
14
Tip: Classes
class Foo {
constructor(bar) {
this.bar = bar;
}
baz() {
return 42;
}
}
var Foo = function(bar) {
this.bar = bar;
}
Foo.prototype.baz = function() {
return 42;
}
15
Trap: forgetting about super()class Foo {
constructor(baz) {
this.baz = baz;
}
}
class Baz extends Foo {
constructor(baz) {
super(baz);
console.log(this.baz);
}
} 16
class Foo {
shout() {
console.log(‘foo!’);
}
}
class Baz extends Foo {
shout() {
super.shout();
console.log(‘baz!’);
}
}
Tip: block scoping
function foo() {
for (var i = 0; i < 2; i++) {
var a = i;
}
console.log(a); // 1
}
function foo() {
for (var i = 0; i < 2; i++) {
let a = i;
}
console.log(a); // ReferenceError
}
17
Trap: Temporal Dead Zone (TDZ)
{
console.log(x); // undefined
var x = ‘codecamp’;
}
{
console.log(x); // ReferenceError
let x = ‘codecamp’;
}
18
Trap: Temporal Dead Zone (TDZ)
Section 13.3.1 in standard (sorry!):
let and const declarations define variables that are scoped to the running execution context’s LexicalEnvironment. The variables are created when their containing Lexical Environment is instantiated but may not be accessed in any way until the variable’s LexicalBinding is evaluated. [...]
19
Trap: Temporal Dead Zone (TDZ)var _temporalUndefined = {};
var x = _temporalUndefined;
function _temporalAssertDefined(val, name, undef) {
if (val === undef) {
throw new ReferenceError(name + " is not defined - temporal dead zone");
}
return true;
}
console.log(_temporalAssertDefined(x, "x", _temporalUndefined) && x);
x = ‘codecamp’;
20Your performance-related concerns: http://kpdecker.github.io/six-speed/
Tip: Iterators/ Generators and for...of
var a = [1, 3, 3, 7];
for (var e of a) {
console.log(e);
}
var a = [1, 3, 3, 7];
var l = a.length;
for (var i = 0; i < l; i++) {
console.log(a[i]);
}
21
Trap: Iterators and constants
var a = [1, 3, 3, 7];
for (const e of a) {
console.log(e);
}
var a = [1, 3, 3, 7];
var l = a.length;
for (const i = 0; i < l; i++) {
console.log(a[i]);
}
22http://stackoverflow.com/questions/31987465/ecmascript-2015-const-in-for-loops
Trap: Iterators and constants
for (const e of a) {
console.log(e);
}
const it = a[Symbol.iterator]();
let res;
while (res = it.next() && !res.done) {
const e = __res.value;
console.log(e);
}
23http://stackoverflow.com/questions/31987465/ecmascript-2015-const-in-for-loops
Tip: Promises
xhr(‘https://foo.com/’
function(resp) {
readHTML(resp,
function(html) {},
function(err) {})
},
function(err) {}
);
xhr(‘https://foo.com/’)
.then(readHTML)
.then(function(html) {})
.catch(function(err) {});
24
Tip: Promises
function xhr(url) {
return new Promise(function(resolve, reject) {
try {
// do some async work then...
resolve(data);
} catch(e) {
// if something goes wrong...
reject(e);
}
});
}25
Trap: forgetting to return
xhr(‘https://foo.com/’)
.then((data) => {
readHTML(data);
})
.then((html) => {
console.log(html); // nope
}
.catch(console.error.bind(console));
xhr(‘https://foo.com/’)
.then((data) => {
return readHTML(data);
})
.then((html) => {
console.log(html); // okay
}
.catch(console.error.bind(console));
26
Trap: passing a non-function to .then()
xhr(‘https://foo.com/’)
.then(readHTML())
.then((result) => {
// XHR response
});
xhr(‘https://foo.com/’)
.then(readHTML)
.then((result) => {
// HTML response
});
27
Trap: .then(resolve, reject)
xhr(‘https://foo.com’)
.then(() => {
throw new ReferenceError;
}
.catch((err) => {
// never gonna give you up
console.log(err);
});
xhr(‘https://foo.com’)
.then(() => {
throw new ReferenceError;
},
(err) => {
// oblivious
console.log(err);
});
28
Trap: Array.forEach vs. Promises
getURLs()
.then((urls) => {
return
urls.forEach(readHTML);
})
.then(() => {
console.log(‘all urls read?’);
})
.catch(console.error.bind(console));
getURLs()
.then((urls) => {
return
Promise.all(urls.map(readHTML);
})
.then(() => {
console.log(‘all urls read!’);
})
.catch(console.error.bind(console));
29
Tip: Promise-driven architecture
function foo() {
return 42;
}
function foo() {
return Promise.resolve(42);
}
30
Tip: Reflect.apply
a = [99, 111, 100, 101, 99, 97, 109, 112];
String.fromCharCode.apply(null, a);
String.fromCharCode.call(null, a[0], a[1]));
a = [99, 111, 100, 101, 99, 97, 109, 112];
Reflect.apply(String.fromCharCode, null, a);
31
Trap: Reflect.apply expects an array
let a = [‘hello’, ‘world’]
Reflect.apply(
e => console.log(e), null, a);
let a = [‘hello’, ‘world’]
Reflect.apply(
e => console.log(e), null, [a]);
Reflect.apply(console.log, console, a);
32
Tip: simple things
delete foo[‘bar’]
parseInt(‘1337’, 10)
Reflect.deleteProperty(foo, ‘bar’)
Number.parseInt(‘1337’, 10)
33
Fin
● ECMAScript 2015 brings many nice features● Solves some of ES5’s strangeness
○ Hopefully we won’t have to revisit “The Good Parts”● Browsers should really start catching up
○ Babel is here to stay○ Transpilers will always have a performance handicap
● We had 5 ReferenceErrors
34
● http://jsrocks.org/2015/01/temporal-dead-zone-tdz-demystified/
● https://stackoverflow.com/questions/31987465/ecmascript-2015-const-in-for-loops
● http://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html
Resources
35
www.meetup.com/Iasi-JS/ www.meetup.com/Papers-We-Love-Iasi