ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了。
(2016年6月,发布了小幅修订的《ECMAScript 2016 标准》(简称 ES2016)。由于变动非常小(只新增了数组实例的includes
方法和指数运算符),因此 ES2016 与 ES2015 基本上是同一个标准,都被看作是 ES6。)
声明变量。它的用法类似于var
,但是所声明的变量,只在let
命令所在的代码块内有效.不存在变量提升
const
声明一个只读的常量。一旦声明,常量的值就不能改变。
const
的作用域与let
命令相同:只在声明所在的块级作用域内有效。
const
命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。
对于复合类型的变量,变量名不指向数据,而是指向数据所在的地址。const
命令只是保证变量名指向的地址不变,并不保证该地址的数据不变,所以将一个对象声明为常量必须非常小心。
解构赋值(destructuring assignment)语法是一个Javascript表达式,它使得从数组或者对象中提取数据赋值给不同的变量成为可能。
以前,为变量赋值,只能直接指定值。
var a = 1;
var b = 2;
var c = 3;
ES6允许写成下面这样。
var [a, b, c] = [1, 2, 3];
上面代码表示,可以从数组中提取值,按照对应位置,对变量赋值。
本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。
如果解构不成功,变量的值就等于undefined
。
另一种情况是不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组。这种情况下,解构依然可以成功。
解构赋值允许指定默认值。
var [foo = true] = [];
foo // true
[x, y = ‘b‘] = [‘a‘]; // x=‘a‘, y=‘b‘
[x, y = ‘b‘] = [‘a‘, undefined]; // x=‘a‘, y=‘b‘
注意,ES6内部使用严格相等运算符(===
),判断一个位置是否有值。所以,如果一个数组成员不严格等于undefined
,默认值是不会生效的。
如果默认值是一个表达式,那么这个表达式是惰性求值的,即只有在用到的时候,才会求值。
解构不仅可以用于数组,还可以用于对象。
对象的解构赋值是下面形式的简写
var { foo: foo, bar: bar } = { foo: "aaa", bar: "bbb" };
也就是说,对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。
var { foo: baz } = { foo: "aaa", bar: "bbb" };
baz // "aaa"
foo // error: foo is not defined
上面代码中,真正被赋值的是变量baz
,而不是模式foo
。
var { foo, bar } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"
对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
如果变量名(左边)与属性名(右边)不一致,必须写成下面这样。
var { foo: baz } = { foo: ‘aaa‘, bar: ‘bbb‘ };
baz // "aaa"
let obj = { first: ‘hello‘, last: ‘world‘ };
let { first: f, last: l } = obj;
f // ‘hello‘
l // ‘world‘
var node = {
loc: {
start: {
line: 1,
column: 5
}
}
};
和数组一样,解构也可以用于嵌套结构的对象。
var { loc: { start: { line }} } = node;
line // 1
loc // error: loc is undefined
start // error: start is undefined
上面代码中,只有line
是变量,loc
和start
都是模式,不会被赋值。
对象的解构也可以指定默认值。
默认值生效的条件是,对象的属性值严格等于undefined
。
如果解构失败,变量的值等于undefined
。
对象的解构赋值,可以很方便地将现有对象的方法,赋值到某个变量。
let { log, sin, cos } = Math;
上面代码将Math
对象的对数、正弦、余弦三个方法,赋值到对应的变量上,使用起来就会方便很多。
字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。
const [a, b, c, d, e] = ‘hello‘;
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"
解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。
let {toString: s} = 123;
s === Number.prototype.toString // true
let {toString: s} = true;
s === Boolean.prototype.toString // true
上面代码中,数值和布尔值的包装对象都有toString
属性,因此变量s
都能取到值。
解构赋值的规则是,只要等号右边的值不是对象,就先将其转为对象。由于undefined
和null
无法转为对象,所以对它们进行解构赋值,都会报错。
let { prop: x } = undefined; // TypeError
let { prop: y } = null; // TypeError
函数的参数也可以使用解构赋值。
function add([x, y]){
return x + y;
}
add([1, 2]); // 3
上面代码中,函数add
的参数表面上是一个数组,但在传入参数的那一刻,数组参数就被解构成变量x
和y
。对于函数内部的代码来说,它们能感受到的参数就是x
和y
。
new Promise(executor); new Promise(function(resolve, reject) { ... });
Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve
和reject
。它们是两个函数,由JavaScript引擎提供,不用自己部署。
The Promise
object is used for asynchronous computations. A Promise
represents an operation that hasn‘t completed yet, but is expected in the future.
一个Promise对象代表着一个还未完成,但预期将来会完成的操作。
因为Promise.prototype.then
和
方法返回 promises对象, 所以它们可以被链式调用Promise.prototype.catch
Promise是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。
(1)对象的状态不受外界影响。
Promise对象代表一个异步操作,有三种状态:
只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。
Promise对象的状态改变,只有两种可能:从Pending变为Resolved和从Pending变为Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
Promise
原型Promise.prototype.constructor
返回创建了实例原型的函数. 默认为 Promise
函数.方法
作用是为Promise实例添加状态改变时的回调函数。前面说过,then
方法的第一个参数是Resolved状态的回调函数,第二个参数(可选)是Rejected状态的回调函数。
Promise.prototype.then(onFulfilled, onRejected)
添加肯定和否定回调到当前 promise, 返回一个新的 promise, 将以回调的返回值 来resolve.
then
方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then
方法后面再调用另一个then
方法。
Promise.prototype.catch(onRejected)
添加一个否定(rejection) 回调到当前 promise, 返回一个新的promise。如果这个回调被调用,新 promise 将以它的返回值来resolve,否则如果当前promise 进入fulfilled状态,则以当前promise的肯定结果作为新promise的肯定结果.Promise.prototype.catch
方法是.then(null, rejection)
的别名,用于指定发生错误时的回调函数。Promise.all(iterable)
方法返回一个promise,该promise会等iterable参数内的所有promise都被resolve后被resolve,或以第一个promise被reject的原因而reject 。
Promise.all
方法用于将多个Promise实例,包装成一个新的Promise实例。
var p = Promise.all([p1, p2, p3]);
p
的状态由p1
、p2
、p3
决定,分成两种情况。
(1)只有p1
、p2
、p3
的状态都变成fulfilled
,p
的状态才会变成fulfilled
,此时p1
、p2
、p3
的返回值组成一个数组,传递给p
的回调函数。
(2)只要p1
、p2
、p3
之中有一个被rejected
,p
的状态就变成rejected
,此时第一个被reject
的实例的返回值,会传递给p
的回调函数。
只有这p1,p2,p3实例的状态都变成fulfilled
,或者其中有一个变为rejected
,才会调用Promise.all
方法后面的回调函数。
Promise.race
方法同样是将多个Promise实例,包装成一个新的Promise实例。
var p = Promise.race([p1,p2,p3]);
上面代码中,只要p1
、p2
、p3
之中有一个实例率先改变状态,p
的状态就跟着改变。那个率先改变的Promise实例的返回值,就传递给p
的回调函数。
Promise.race
方法的参数与Promise.all
方法一样,如果不是Promise实例,就会先调用下面讲到的Promise.resolve
方法
有时需要将现有对象转为Promise对象,Promise.resolve
方法就起到这个作用。
Promise.resolve
方法的参数分成四种情况。
(1)参数是一个Promise实例
如果参数是Promise实例,那么Promise.resolve
将不做任何修改、原封不动地返回这个实例。
(2)参数是一个thenable
对象
thenable
对象指的是具有then
方法的对象,比如下面这个对象。
Promise.resolve
方法会将这个对象转为Promise对象,然后就立即执行thenable
对象的then
方法。
(3)参数不是具有then
方法的对象,或根本就不是对象
如果参数是一个原始值,或者是一个不具有then
方法的对象,则Promise.resolve
方法返回一个新的Promise对象,状态为Resolved
。
(4)不带有任何参数
Promise.resolve
方法允许调用时不带参数,直接返回一个Resolved
状态的Promise对象。
原文:http://www.cnblogs.com/oneplace/p/5660488.html