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()
// []
...args
只能出现在函数参数列表的最后一个位置
// 报错
function foo(...args, name) { // Syntax error: Unexpected token
console.log(name)
}
// 正常运行
function bar(name, ...args) {
console.log(name)
}
bar('Bender')
// Bender
arguments
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
call
和 apply
不影响 this
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
self
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
[Symbol.iterator]
方法的对象
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 of
循环
for(let i of iterable) {
console.log(i)
}
// 1, 2, 3, 4
let iterator = iterable[Symbol.iterator]()
iterator.next()
// {"value": 1, "done": false}
[Symbol.iterator]
方法返回的对象next
方法会返回一个对象value
是值done
表明是否结束迭代
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]
next
传值
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
then
会返回一个新的 promise
calculate(1)
.then(calculate)
.then(result => result + 1)
.then(result => console.log(result))
// 4
Promise.resolve
Promise.reject
Promise.all(promiseList)
Promise.race(promiseList)
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
.catch(errorHandler)
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'