On Github llh911001 / es6-must-know
by @llh911001
2016/1/13
if(true) { let a = 1 } console.log(a) // a is not defined
let a = 1 let a = 2 // Duplicate declaration "a"
for (var i=0; i<10; i++) { setTimeout(~function(a) { console.log(a) }(i), 100) } // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
for (let i=0; i<10; i++) { setTimeout(() => { console.log(i) }, 100) } // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
const CONSTANT = 'a constant' CONSTANT = 'something else' // "CONSTANT" is read-only // 重新为一个常量赋值会报错
const CONSTANT // Syntax error: Unexpected token
const CONSTANT = {foo: 1} CONSTANT.foo = 2 // 正常运行
function work(name) { name = name || 'Bender' return name } work() // Bender
function work(name = 'Bender') { return name } work() // Bender
function work(name = 'Bender', hobby = 'drinking') { return `${name} likes ${hobby}` } work() // Bender likes drinking
function work(foo, name = 'Bender', hobby = 'drinking', bar) { return `${name} likes ${hobby}` } work() // Bender likes drinking
function foo(...args) { console.log(args); } foo(1, 2, 3) // [1, 2, 3] foo() // []
// 报错 function foo(...args, name) { // Syntax error: Unexpected token console.log(name) } // 正常运行 function bar(name, ...args) { console.log(name) } bar('Bender') // Bender
function foo(a, b, c) { return a + b + c } foo(...[1, 2, 3]) // 6
let a = [3, 4, 5] let b = [1, 2, ...a, 6, 7] console.log(b) // [1, 2, 3, 4, 5, 6, 7]
function foo(a, b, c) { return a + b + c } foo(...[1, 2, 3, 4, 5, 6]) // 6 // 后面的被忽略了
let values = [42, 73] let [a, b] = values console.log(a, b) // 42, 73
let bender = {name: 'Bender', hobby: 'drinking'} let {name, hobby} = bender console.log(name, hobby) // Bender, drinking
let a = 1, b = 2 [a, b] = [b, a] console.log(a, b) // 2, 1
let values = [1, 2, 3] let [, a, b, c] = values console.log(a, b, c) // 2, 3, undefined
let name = 'Bender' let result = `Hello, ${name}` console.log(result) // Hello, Bender
let a = 42, b = 73 let result = `a + b is ${a + b}` console.log(result) // a + b is 115
let result = `Hello there, Bender! ` console.log(result) // Hello\n there, Bender!
let name = 'Bender' let result = test `Hello,${name}!` function test(literals, ...values) { console.log(literals) // ['Hello,', '!'] console.log(values) // ['Bender'] return 'test' } console.log(result) // test
class Animal { // ... } let animal = new Animal()
class Animal { constructor(name) { this._name = name } getName() { return this._name } } let animal = new Animal('kitty') animal.getName() // kitty
class Animal { constructor(name) { this._name = name } get name() { return this._name } set name(newName) { this._name = newName } } let animal = new Animal('kitty') console.log(animal.name) // kitty animal.name = 'doge' console.log(animal.name) // doge
class Animal { constructor(name) { this._name = name } static foo() { return 'I am a static method' } } let animal = new Animal('kitty') animal.foo() // animal.foo is not a function Animal.foo() // I am a static method
class Animal { constructor(name) { this._name = name } get name() { return this._name } set name(newName) { this._name = newName } say() { return 'I am an animal' } } class Cat extends Animal { say() { return 'I am a cat' } } let cat = new Cat('kitty') cat.name // kitty cat.say() // I am a cat
class Cat extends Animal { constructor(name, pet) { super(name) this._pet = pet } get pet() { return this._pet } } let cat = new Cat('kitty', 'Bender') console.log(cat.pet) // Bender
class Cat extends Animal { // ... say() { return super() + '!' } } // 或者 class Cat extends Animal { // ... say() { return super.say() + '!' } }
let cat = new Cat('kitty') cat instanceOf Cat // true cat instanceOf Animal // true
let add = (a, b) => a + y
let add = (x, y) => x + y // 必需 let square = x => x * x // 不必需 let compute = () => square(add(5, 3)) // 必需 let result = compute() // 64
// 正常运行 let add = (x, y) => x + y // 或者 let add = (x, y) => { return x + y } // 返回一个对象 {a: 1} // 失败 let test = () => { a: 1 } // 成功 let test = () => ({ a: 1 }) // 或者 let test = () => { return {a: 1} }
function A(name) { this._name = name } A.prototype.later = function() { var self = this setTimeout(function() { console.log(self._name) }, 100) } var a = new A('Bender') a.later() // Bender
class A { constructor(name) { this._name = name } later() { setTimeout(() => console.log(this._name), 100) } } let a = new A('Bender') a.later() // Bender
class A { constructor(name) { this._name = name } } let a = new A('Bender') a.foo = function() { console.log(this._name) } a.bar = () => { console.log(this._name) } a.foo.call({_name: 'foo'}) // foo a.bar.call({_name: 'bar'}) // Cannot read property '_name' of undefined
let s1 = Symbol() s1.toString() // Symbol() type of s1 // symbol let s2 = Symbol('a symbol') type of s2 // symbol s2.toString() // Symbol(a symbol)
let s = new Symbol() // Symbol is not a constructor
let s1 = Symbol('a symbol') let s2 = Symbol('a symbol') s1 === s2 // false
let foo = 'foo' let bar = Symbol() let obj = { foo: foo, [bar]: 'bar' // 注意新语法 } console.log(obj.foo) // foo console.log(obj[bar]) // bar
let result = [] for(let a in obj) { result.push(a) } console.log(a) // ['foo']
let keys = Object.getOwnPropertyNames(obj) console.log(keys) // ['foo']
let smbs = Object.getOwnPropertySymbols(obj) console.log(obj[smbs[0]]) // bar
let iterable = { index: 0, [Symbol.iterator]() { return { next: () => { if(this.index < 5) { this.index++ return {done: false, value: this.index-1} } else { return {done: true, value: this.index} } } } } }
for(let i of iterable) { console.log(i) } // 1, 2, 3, 4
let iterator = iterable[Symbol.iterator]() iterator.next() // {"value": 1, "done": false}
let numbers = function* () { yield 1 yield 2 yield 3 } let generator = numbers() generator.next() // {"value": 1, "done": false} for(let i of generator) { console.log(i) } // 2, 3 generator.next() // {"done": true}
function* foo() { yield 2 yield 3 } function* bar() { yield 1 foo() // 没有任何效果 yield 4 } [...bar()] // [1, 4] function* bar() { yield 1 yield* foo() yield 4 } [...bar()] // [1, 2, 3, 4]
function* foo(x) { var y = 2 * (yield (x + 1)); var z = yield (y / 3); return (x + y + z); } var it = foo(5); console.log(it.next()); // { "value": 6, "done": false } console.log(it.next(12)); // { "value": 8, "done": false } console.log(it.next(13)); // { "value": 42, "done": true }
export default foo export let foo = 'foo' export {foo, bar} export {foo as bar} export {foo as default} // 等价于 export default foo
import foo from 'foo' import {foo, bar} from 'baz' import {foo as bar} from 'baz' import {default} from 'foo' import {deafult as foo} from 'foo' import foo, {bar, baz} from 'foo' import * as foo from 'foo' import 'foo'
//------ lib.js ------ export let counter = 0; export function inc() { counter++; } //------ main.js ------ import {inc, counter} from 'lib'; console.log(counter); // 0 inc(); console.log(counter); // 1
let p = new Promise((resolve, reject) => { // ... }) p.then(fulfillHandler, rejectHandler) .catch(errorHandler)
let calculate = function(value) { return new Promise((resolve, reject) => { setTimeout(() => { resolve(value + 1) }, 0) }) } calculate(1) .then(calculate) .then(calculate) .then(result => console.log(result)) // 4
calculate(1) .then(calculate) .then(result => result + 1) .then(result => console.log(result)) // 4
let p = () => { console.log('a') return Promise.resolve() } p() .then(() => console.log('b')) .then(() => { throw new Error('error') }) // 为何要加大括号?把 throw 换成 return 如何? .then(() => console.log('c'), () => console.log('d')) // a, b, d
let p = () => { console.log('a') return Promise.resolve() } p() .then(() => console.log('b')) .then(() => { throw new Error('error') }) .catch(() => console.log('d')) .catch(() => console.log('e')) .then(() => console.log('f')) // a, b, d, f
let map = new Map() map.set('key', 42) map.get('key') // 42 map.has('key') // true map.delete('key') map.has('key') // false
let set = new Set([1, 2, 2, 3]) set.size // 3 for(let i of set) { console.log(i) } // 1, 2, 3 let o = {foo: 1} let s = new Set() s.add(o) s.add(o) s.add({foo: 1}) s.size // 2 s.has({foo: 1}) // false
let a = ['a', 'b', 'c'] let values = [...a.values()] // ['a', 'b', 'c'] let keys = [...a.keys()] // [0, 1, 2] let entries = [...a.entries()] [[0,'a'],[1,'b'],[2,'c']] Array.from(a.values()) // ['a', 'b', 'c']
let foo = Object.assign({}, {a: 1, b: 2}, {a: 'a', c: 'c'}) // {a: 'a', b: 2, c: 'c'} let key2 = 'second' let bar = { key1: 'hello', [key2 + 'Key']: 'world' } bar.secondKey === 'world'