diff --git a/docs/array.md b/docs/array.md index bea8340..43c1a64 100644 --- a/docs/array.md +++ b/docs/array.md @@ -232,15 +232,13 @@ contains(["foo", "bar"], "baz"); // => false ## 数组推导 -ES6提供简洁写法,允许直接通过现有数组生成新数组,这被称为数组推导(array comprehension)。 +数组推导(array comprehension)提供简洁写法,允许直接通过现有数组生成新数组。这项功能没有被列入ES6,而是推迟到了ES7。 ```javascript - var a1 = [1, 2, 3, 4]; var a2 = [for (i of a1) i * 2]; a2 // [2, 4, 6, 8] - ``` 上面代码表示,通过for...of结构,数组a2直接在a1的基础上生成。 @@ -250,7 +248,6 @@ a2 // [2, 4, 6, 8] for...of后面还可以附加if语句,用来设定循环的限制条件。 ```javascript - var years = [ 1954, 1974, 1990, 2006, 2010, 2014 ]; [for (year of years) if (year > 2000) year]; @@ -261,8 +258,8 @@ var years = [ 1954, 1974, 1990, 2006, 2010, 2014 ]; [for (year of years) if (year > 2000 && year < 2010) year]; // [ 2006] - ``` + 上面代码表明,if语句写在for...of与返回的表达式之间,可以使用多个if语句。 数组推导可以替代map和filter方法。 diff --git a/docs/intro.md b/docs/intro.md index 6200135..addd100 100644 --- a/docs/intro.md +++ b/docs/intro.md @@ -4,9 +4,13 @@ ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准,已经 ES6的目标,是使得JavaScript语言可以用来编写大型的复杂的应用程序,成为企业级开发语言。 +标准的制定者计划,以后每年发布一次标准,使用年份作为标准的版本。因为当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015。 + ## ECMAScript和JavaScript的关系 -很多初学者会感到困惑:ECMAScript和JavaScript到底是什么关系?简单说,ECMAScript是JavaScript语言的国际标准,JavaScript是ECMAScript的实现。 +很多初学者感到困惑:ECMAScript和JavaScript到底是什么关系? + +简单说,ECMAScript是JavaScript语言的国际标准,JavaScript是ECMAScript的实现。 要讲清楚这个问题,需要回顾历史。1996年11月,JavaScript的创造者Netscape公司,决定将JavaScript提交给国际标准化组织ECMA,希望这种语言能够成为国际标准。次年,ECMA发布262号标准文件(ECMA-262)的第一版,规定了浏览器脚本语言的标准,并将这种语言称为ECMAScript。这个版本就是ECMAScript 1.0版。 diff --git a/docs/iterator.md b/docs/iterator.md index c0e2b2b..bab5918 100644 --- a/docs/iterator.md +++ b/docs/iterator.md @@ -722,3 +722,14 @@ for (let value of myArray) { - 不同用于forEach方法,它可以与break、continue和return配合使用。 - 提供了遍历所有数据结构的统一操作接口。 +下面是一个使用break语句,跳出for...of循环的例子。 + +```javascript +for (var n of fibonacci) { + if (n > 1000) + break; + console.log(n); +} +``` + +上面的例子,会输出斐波纳契数列小于等于1000的项。如果当前项大于1000,就会使用break语句跳出for...of循环。 diff --git a/docs/object.md b/docs/object.md index f7bbe24..c789f62 100644 --- a/docs/object.md +++ b/docs/object.md @@ -989,6 +989,86 @@ proxy.foo // TypeError: Revoked Proxy.revocable方法返回一个对象,该对象的proxy属性是Proxy实例,revoke属性是一个函数,可以取消Proxy实例。上面代码中,当执行revoke函数之后,再访问Proxy实例,就会抛出一个错误。 +## Reflect + +Reflect对象与Proxy对象一样,也是ES6为了操作对象而提供的新API。Reflect对象的设计目的有这样几个。 + +- 将Object对象的一些明显属于语言层面的方法,放到Reflect对象上。现阶段,某些方法同时在Object和Reflect对象上部署。 +- Reflect对象的方法与Proxy对象的方法一一对应,这是为了让Proxy对象可以方便地有一个原始方法,作为修改行为基础。 + +```javascript +Proxy(target, { + set: function(target, name, value, receiver) { + var success = Reflect.set(target,name, value, receiver); + if (success) { + log('property '+name+' on '+target+' set to '+value); + } + return success; + } +}); +``` + +上面代码中,Proxy方法拦截target对象的属性赋值行为。它采用Reflect.set方法将值赋值给对象的属性,然后再部署额外的功能。 + +下面的例子中,Reflect对象方法基本与Object对象的对应方法一致。 + +```javascript +var O = {a: 1}; +Object.defineProperty(O, 'b', {value: 2}); +O[Symbol('c')] = 3; + +Reflect.ownKeys(O); // ['a', 'b', Symbol(c)] + +function C(a, b){ + this.c = a + b; +} +var instance = Reflect.construct(C, [20, 22]); +instance.c; // 42 +``` + +Reflect对象的方法清单如下。 + +- Reflect.getOwnPropertyDescriptor(target,name) +- Reflect.defineProperty(target,name,desc) +- Reflect.getOwnPropertyNames(target) +- Reflect.getPrototypeOf(target) +- Reflect.deleteProperty(target,name) +- Reflect.enumerate(target) +- Reflect.freeze(target) +- Reflect.seal(target) +- Reflect.preventExtensions(target) +- Reflect.isFrozen(target) +- Reflect.isSealed(target) +- Reflect.isExtensible(target) +- Reflect.has(target,name) +- Reflect.hasOwn(target,name) +- Reflect.keys(target) +- Reflect.get(target,name,receiver) +- Reflect.set(target,name,value,receiver) +- Reflect.apply(target,thisArg,args) +- Reflect.construct(target,args) + +上面这些方法中,有几点需要注意。 + +- Reflect.get(target,name,receiver) 查找target对象的name属性。如果name属性部署了读取函数,则读取函数的this绑定receiver。 + +- Reflect.set(target, name, value, receiver) 设置target对象的name属性等于value。如果name属性设置了赋值函数,则赋值函数的this绑定receiver。 + +- Reflect.construct(target, args)等同于`new target(...args)`。 + +- Reflect.apply(fun,thisArg,args)等同于`Function.prototype.apply.call(fun,thisArg,args)`。 + +- Reflect.set()、Reflect.defineProperty()、Reflect.freeze()、Reflect.seal()和Reflect.preventExtensions()返回一个布尔值,表示操作是否成功。它们对应的Object方法,失败时都会抛出错误。 + +```javascript +// 失败时抛出错误 +Object.defineProperty(obj, name, desc); +// 失败时返回false +Reflect.defineProperty(obj, name, desc); +``` + +上面代码中,Reflect.defineProperty方法的作用与Object.defineProperty是一样的,都是为对象定义一个属性。但是,Reflect.defineProperty方法失败时,不会抛出错误,只会返回false。 + ## Object.observe(),Object.unobserve() Object.observe方法用来监听对象(以及数组)的变化。一旦监听对象发生变化,就会触发回调函数。