AirJD 焦点
AirJD

没有录音文件
00:00/00:00
加收藏

高效的ES6 (ECMAScript 6入门教程) by teppeis(日)

发布者 jser
发布于 1442192819811  浏览 6567 关键词 前端, English, JavaScript 
分享到

第1页

Effective ES6

@teppeis

YAPC::Asia Tokyo 2015 Aug 21



第2页

Hello!

• Teppei Sato, @teppeis • Cybozu, Inc. / kintone • This is my first and last YAPC :)



第3页

I created



第4页

http://cybozushiki.cybozu.co.jp/articles/m000978.html



第5页

kintone.com



第6页

MUST BUY!



第7页

Today talk about:

• Introduce ES6 features

• Deprecated best-practice/patterns

• What’s ES2016, ES2017… • How to use ES6 from now



第8页

Background



第9页

“My solution to the challenging requirements and crazy-short schedule was to make JavaScript extremely malleable from the start.”

–Brendan Eich

from Effective JavaScript

https://www.flickr.com/photos/jsconf/4587502948/



第10页

“JavaScript: The world’s most misunderstood programming language”

–Douglas Crockford

2001, http://www.crockford.com/javascript/javascript.html

https://www.flickr.com/photos/charliebrewer/2897862701/



第11页

JavaScript has many pitfalls…

• Prototype inheritance (No class) • new, this • Function scope (No block scope) • Global variables (No module system) • Hoisting • NaN, undefined • typeof null • with, eval



第12页

Example: No Class

• Use Prototype to emulate Classes

function Person(name) { this.name = name;

} Person.prototype.greet = function() {

console.log("Hello, I'm " + this.name); }; var bob = new Person("Bob"); bob.greet(); // "Hello, I'm Bob"



第13页

If you miss "new", dangerous!

function Person(name) { this.name = name;

}

// Oh! You forget `new` var bob = Person("Bob"); console.log(bob); // undefined

// Global leak!!!!!!!!!! console.log(window.name); // "Bob"



第14页

We've made best-practices a.k.a. “work around”



第19页

Practice: Be sure to call with "new"

function Person(name) { // check! if (this instanceof Person) { return new Person(name); } this.name = name;

} // without `new` var bob = Person("Bob"); bob.greet(); // "Hello, I'm Bob"



第20页

ES6!



第21页

ECMAScript 6

• Published on June 17, 2015

• Formally "ECMAScript 2015" • 6 years! from ES5



第22页

ECMAScript 6

• Modern syntax fixing pitfalls • Better support for large applications • No (or few) breaking changes



第23页

For example: ES6 Classes



第24页

ES6 Classes: Simple!

class Person { constructor(name) { this.name = name; }

greet() { console.log("Hello, I'm " + this.name);

} }

var bob = new Person("Bob"); bob.greet();

// without `new` var bob = Person("Bob"); // Error!



第25页

OUTCOlFaDsAsTeEs! based on Prototype

function Person(name) { this.name = name;

} Person.prototype.greet = function() {

console.log("Hello, I'm " + this.name); }; var bob = new Person("Bob"); bob.greet(); // "Hello, I'm Bob"



第26页

OUTBOeF



DATE!

sure



to



call



with



`new`



function Person(name) { // check! if (this instanceof Person) { return new Person(name); } this.name = name;

} // without `new` var bob = Person("Bob"); bob.greet(); // "Hello, I'm Bob"



第27页

New ES6 features deprecates yesterday’s best-practices No more altJS!

https://www.flickr.com/photos/jorge-11/2765216505/



第28页

Can I use ES6 now?



第29页

ES6 compatibility table



https://kangax.github.io/compat-table/es6/



第30页

You can use ES6 now!

• Modern browsers and io.js (node.js) support  half of ES6 features.

• Safari 9 (WebKit) will support many ES6 features soon. • Except for IE11…



第31页

Transpiler and polyfill

• ES6 Transpiler: source code converter from ES6 to ES5/ES3

• ES6 Polyfill: library to provide ES6 built-in classes, functions and objects for ES5/ES3



第32页

Babel



第33页

Babel

• The most compatible (71%) ES6 transpiler • Integrated with core-js (polyfill library) • Usage:

• CLI: npm i -g babel • Browserify: babelify • REPL on the Web (Try it out!)



第34页

Babel REPL on the Web



第35页

ES6 features



第36页

ES6 features

• New syntax • New built-in classes and objects • Improvement of existing classes



第37页

ES6 features

• New syntax • New built-in classes and objects • Improvement of existing classes



第38页

New syntax



• Arrow Function • Classes • Modules • Block Scope (let/const) • Extended Object

Literal • Default Params • Rest Params • Spread Operator



• Destructuring • Iterator • Generator • Template Literal • Tail Call Optimization



第39页

Arrow Function



第40页

Prefer arrow function

// ES5 old function var add = function(a, b) {

return a + b; }; // ES6 arrow function! var add = (a, b) => {

return a + b; }; var add = (a, b) => a + b; var square = n => n * n; // good for array filter chains [1, 2, 3, 4].filter(n => n % 2 === 0).map(n => n * n);



第41页

OUTAOFsDsAiTgEn! “this” to “self”

var john = { name: "John", helloLater: function() { // save `this` as `self` var self = this; setTimeout(function() { // `this` is not available. use `self`. console.log("Hello, I'm " + self.name); }, 1000); }

} john.helloLater(); // "Hello, I'm John" after 1sec



第42页

Arrow function don’t need "self"

let john = { name: "John", helloLater: function() { // use arrow function setTimeout(() => { // `this` is available here! console.log("Hello, I'm " + this.name); }, 1000); }

} john.helloLater(); // "Hello, I'm John" after 1sec



第43页

Classes



第44页

ES6 Classes

class Person { constructor(name) { this.name = name; }

greet() { console.log("Hello, I'm " + this.name);

} }

var bob = new Person("Bob"); bob.greet();



第45页

OUTCOFlaDsATsEe!s based on Prototype

function Person(name) { this.name = name;

} Person.prototype.greet = function() {

console.log("Hello, I'm " + this.name); }; var bob = new Person("Bob"); bob.greet(); // "Hello, I'm Bob"



第46页

OUTHOFaDnAdTEm! ade inheritance function

// handmade function to extend function __extends(child, parent) {

for (var key in parent) { if (Object.prototype.hasOwnProperty.call(parent, key)) { child[key] = parent[key]; }

} function ctor() {

this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; function Programmer(name, language) { Person.call(this, name); this.language = language; } __extends(Programmer, Person);



第47页

ES6 Class inheritance

• with "extends" and "super" • can extends built-in classes like "Error"

class Programmer extends Person { constructor(name, language) { super(name); this.language = language; }

greet() { super.greet(); console.log("I like " + this.language);

} }

var bob = new Programmer("Bob", "JavaScript"); bob.greet(); // "Hello, I'm Bob" // "I like JavaScript"



第48页

Modules



第49页

OUTMOFoDAdTuE!le pattern

// Global module var myModule = (function () {

// Module object var module = {},

privateVariable = "Hello World";

function privateMethod() { // ...

}

module.publicProperty = "Foobar"; module.publicMethod = function () {

console.log( privateVariable ); };

return module; })();



第50页

OUTCOFoDmATmE! onJS Modules

• node.js/npm friendly • browserify/webpack to build for browser

// import var foo = require('foo'); foo(); // export exports.bar = function() {

console.log('bar'); }



第51页

ES6 Modules

• run anywhere (browsers, node.js…) if ES6 available • easy to parse statically • strict mode by default in modules

// export (./module.js) export var foo = "foo!"; export function bar() {} export class Baz {

baz() {} }

// import import {foo, bar, Baz} from "./module"; console.log(foo); // "foo!" bar(); new Baz();



第52页

OUTWOF rDiAtTeE!“use strict;”

• Strict mode is useful even in ES6. • In ES6 Module, always strict mode! • You don’t have write “use strict;” in ES6 modules.

"use strict"; // Error! with (obj) {} // Error! var obj = {a: 1, a: 1};



第53页

Block Scope (let/const)



第54页

ES5 has only function scope

function foo() { var num = 1; // ... too many statements if (true_condition) { // same scope! overwrite above `num`! var num = 2; // .. some process } console.log(num); // 2 !!!

}



第55页

Weird hoisting

var a = 'outer'; function bar() {

console.log(a); var a = 'inner'; } bar(); // undefined !!!



第56页

Weird hoisting

var a = 'outer'; function bar() {

// hoisting! var a; console.log(a); a = 'inner'; } bar(); // undefined !!!



第57页

OUTPOFlaDAcTeE!“var”s at the top of the scope

• for function scope and hoisting

function init() { // `var` once at the top of the scope! var i, cell, cells = document.getElementsByTagName('td'); for (i = 0; i < cells.length; i++) { cell = cells[i]; cell.addEventListener('click', function() { cell.style.backgroundColor = '#00F'; }, false); }

}



第58页

Use ES6 let or const anytime!

• let and const create block scope • no hoisting • no more "var"!

function foo() { let num = 1; // ... too many statements

if (true_condition) { // different scope! let num = 2;

}

console.log(num); // 1 }



第59页

with for-loop

• each iterate creates its own block scope

for (let i = 0; i < 5; i++) { // new block scope is created for each iteration setTimeout(() => console.log(i), i * 100);

} // display "1", "2", "3", "4", "5"



第60页

const

• immutable value (not immutable object) • use like Java's final

const foo = 1; foo = 100; // Error! const foo = 1000; // Error! // properties are mutable const obj = {}; obj.foo = 1; // No error



第61页

Default Parameters



第62页

Incorrect default params

• Incorrect, but occur frequently

function add(a, b) { // if "a" is 0, 1 is assigned to "a". a = a || 1; b = b || 2; return a + b; } add(0, 0); // 1 + 2 = 3



第63页

OUT OHFaDAnTdE!made default params comparing to undefined

function add(a, b) { // correct, but awful.. if (a === undefined) { a = 1; } if (b === undefined) { b = 2; } return a + b;

} add(0, 0); // 0 + 0 = 0



第64页

ES6 Default Parameters

// default value for each param function add(a = 1, b = 2) {

return a + b; } add(); // 1 + 2 = 3 add(0); // 0 + 2 = 2 add(undefined, 0); // 1 + 0 = 1 add(0, 0); // 0 + 0 = 0



第65页

Rest Parameters



第66页

OUTaUOFrsgDeAuT"mEa! regnutsments" for variable-length

function foo(first, second) { console.log("first:", first); console.log("second:", second); // arguments is an ArrayLike, not an Array. var rest = Array.prototype.slice.call(arguments, 2); console.log("rest:", rest);

} foo(1, 2, 3, 4, 5); // first: 1 // second: 2 // rest: [3, 4, 5]



第67页

ES6 Rest Params instead of arguments

• You don’t have to use `arguments`

function foo(first, second, ...rest) { console.log("first:", first); console.log("second:", second); console.log("rest:", rest);

} foo(1, 2, 3, 4, 5); // first: 1 // second: 2 // rest: [3, 4, 5]



第68页

Destructuring



第69页

Destructuring assignment

• Array assignment

let match = /(\d{4})(\d{2})(\d{2})/.exec("20151231"); // match: [2015151231, 2015, 12, 31] let [, year, month, day] = match; console.log(year, month, day); // 2015 12 31 // Swapping [x, y] = [y, x]



第70页

Destructuring assignment

• Object assignment

let {name: a, age: b} = {name: "Bob", age: 20}; console.log(a, b); // "Bob" 20 // shorthand let {name, age} = {name: "Bob", age: 20}; console.log(name, age); // "Bob" 20



第71页

Destructuring assignment

• Function params like "named-params" • Options object param

function draw(x, y, {width = 320, height = 160} = {}) { // do the task

} size(0, 0); size(0, 0, {}); size(0, 0, {width: 1}); size(0, 0, {height: 2}); size(0, 0, {width: 1, height: 2});



第72页

OUTHOFaDnATdEm! ade Options object handling

function draw(x, x, options) { if (options.width === undefined) { options.width = 320; } if (options.height === undefined) { options.height = 320; } // do the task

}



第73页

Template Literal



第74页

OUTCOFoDnATcEa! t with "+" or String#join()

// concat with variables var name = 'Bob'; var str = "Hello, I'm " + name + "."; // create multiple lines var multi = ["line1", "line2", "line3"].join("\n");



第75页

Template Literal

• back-quoted string

// interpolation var name = 'Bob'; var str = `Hello, I'm ${name}.`; // multiple lines var multi = `line1 line2 line3`;



第76页

Extended Object Literal



第77页

Extended object literal for shorthand

let foo = 1; let bar = 2; // shorthand let obj = {foo, bar}; // same as: {foo: foo, bar: bar};

let prefix = 'foo'; let obj = {

// computed property [prefix + 'abc']: 1, // method definition without "function" keyword foo() {

console.log('foo!'); } };



第78页

and…

• Iterator • Spread Operator • Generator • Tail Call Optimization



第79页

ES6 features

• New syntax • New built-in classes and objects • Improvement of existing classes



第80页

New built-in classes and objects

• Promise • Map • Set • WeakMap/WeakSet • TypedArray • Symbol • Proxy/Reflect



第81页

Promise



第82页

OUTCOFaDlAlbTEa! ck args for async API

function asyncTask(a, b, callback) { // ...some async task

if (error) { callback(error);

} else { callback(null, result);

} }

asyncTask(1, 2, function(error, result) { if (error) { // ...error handling }

console.log(result); });



第83页

OUTCOFaDlAlbTEa! ck args for async API

asyncTask1(function(error, result) { if (error) { // ...error handling } asyncTask2(function(error, result) { if (error) { // ...error handling } asyncTask3(function(error, result) { if (error) { // ...error handling } }); });

});



第84页

ES6 Promise

function asyncTask(a, b, callback) { // ...some async task

return new Promise((resolve, reject) => { if (error) { reject(error); } else { resolve(result); }

}); }

asyncTask(1, 2).then(result => { console.log(result);

}).catch(error => { // ...error handling

});



第85页

ES6 Promise

// series asyncTask1().then(result => {

return asyncTask2(); }).then(result => {

return asyncTask3(); }).catch(error => {

// ...error handling });



第86页

ES6 Promise

// parallel Promise.all([

asyncTask1(), asyncTask2(), asyncTask3() ]).then(results => { console.log(results[0]); // result of asyncTask1 });



第87页

Map/Set



第88页

OUTUOFsDeATOE!bject as a dictionary

• some special keys are dangerous

// some keys are dangerous var obj = {}; var key = "toString"; obj[key] = "value1"; String(obj); // TypeError: can't convert obj to string



第89页

OUTUOFsDeATOE!bject as a dictionary

• cannot use an object as a key

// cannot use object as a key var key1 = {name: "key1"}; var key2 = {name: "key2"}; obj[key1] = "value1"; obj[key2] = "value2"; console.log(obj[key1]); // "value2" console.log(Object.keys(obj)); // ["[object Object]"]



第90页

ES6 Map

// no dangerous keys let map = new Map(); map.set("toString", "value1"); map.get("toString"); // "value1" String(map); // "[object Map]" // object as a key let key1 = {}; let key2 = {}; let m = new Map(); m.set(key1, "v1"); m.set(key2, "v2"); m.get(key1); // "v1"



第91页

ES6 Set

• not easy to implement Set in ES5

let set = new Set(); set.add("value1"); console.log(set.size); // 1 // unique set.add("value1"); console.log(set.size); // 1



第92页

and…

• WeakMap/WeakSet • TypedArray • Symbol • Proxy/Reflect



第93页

ES6 features

• New syntax • New built-in classes and objects • Improvement of existing classes



第94页

Improvement of existing classes

• String • RegExp • Array • Object • Math • Number



第95页

Object



第96页

Object.assign

• no more $.extend() !

var target = {a: 1, b: 2}; var s1 = {b: 3, c: 4}; var s2 = {c: 5, d: 6}; var ret = Object.assign(target, s1, s2); console.log(target); // {a: 1, b: 3, c: 5, d: 6}



第97页

String



第98页

Unicode surrogate pair support

• valid

"𠮷野家".codePointAt(0).toString(16); // "20BB7" String.fromCodePoint(0x20BB7); // "𠮷"



第99页

New pitfalls



第100页

What's happen?

if (a => 1) { // ...

}



第101页

Oh! Arrow function!

// expected if (a >= 1) { } // arrow function! confusing.. if (a => 1) { } // clear if ((a) => 1) { }



第102页

ESLint



第104页

ES.next = ES2016?



第105页

The TC39 Process: Annual

• TC39 committee approves acceptance for each stage.

Stage 0: Strawman (idea) Stage 1: Proposal (problem, solution and demo/polyfill) Stage 2: Draft (initial spec) Stage 3: Candidate (review and feedback) Stage 4: Finished (two implementations at least)

• Stage 4 features are published as ES201X on July every year.



第107页

Stage 3: Candidate



第108页

Exponentiation Operator

// x ** y let squared = 2 ** 2; // same as: 2 * 2 let cubed = 2 ** 3; // same as: 2 * 2 * 2 // x **= y let a = 2; a **= 2; // same as: a = a * a;



第109页

Array.prototype.includes(str, pos)

[1, 2, 3].includes(2); // true [1, 2, 3].includes(4); // false [1, 2, NaN].includes(NaN); // true ["a", "b", "c"].includes("a", 0); // true ["a", "b", "c"].includes("a", 1); // false



第110页

Stage 2: Draft



第111页

Object.observe(obj, observer)

let records; function observer(recs) {

records = recs; }

let obj = {id: 1}; Object.observe(obj, observer);

obj.a = 'b'; obj.id++;

Object.deliverChangeRecords(observer); assertChangesAre(records, [

{object: obj, type: 'add', name: 'a'}, {object: obj, type: 'update', name: 'id', oldValue: 1} ]);



第112页

Async/await

async function chainAnimationsAsync(elem, animations) { let ret = null; try { for (let anim of animations) { ret = await anim(elem); } } catch(e) { /* ignore */ } return ret;

}



第113页

SIMD

• Single Instruction Multiple Data • Vector data calculation

let a = SIMD.Float32x4(1.0, 2.0, 3.0, 4.0); let b = SIMD.Float32x4(5.0, 10.0, 15.0, 20.0); let c = SIMD.Float32x4.add(a,b); // c: (6.0, 12.0, 18.0, 24.0)



第114页

How can I get along with ES6 and ES.next?



第115页

May the Babel be with you!

• It's too far for all browsers to support ES6.

• IE11 will live until Jun 10, 2023…

• You will be able to stop transpiling features that browsers support natively.

• Also ES201X features are available via Babel.



第116页

Design your policy: Which ES6 features do you use?

• Which browsers/node.js do you support?

• If you need IE8 (ES3), it's not easy to use ES6…

• Which feature is effective for your project? • Is the feature easy to transpile/polyfill?



第117页

Easy to transpile/polyfill?

• No problem

Arrow function, let/const, Extended Object literal, Classes Extended function params, Template literal, Map/Set, Promise…

• Be careful/Partial

Module, Generator, Symbol

• Hard/Impossible

WeakMap/Set, Proxy, Reflect, Tail Call Optimization



第118页

Customize Babel config

• Specify TC39 Stage (default: Stage 2) • Specify your blacklist features

// .babelrc {

"stage": 3, "blacklist": [

"es6.tailCall", "regenerator" ] }



第119页

Conclusion



第120页

Conclusion

• ES6 is awesome! • Some best-practices are deprecated. • Try ES6 with Babel from now!



第121页

MUST BUY!



第122页

Thanks!



支持文件格式:*.pdf
上传最后阶段需要进行在线转换,可能需要1~2分钟,请耐心等待。