From 6583714f3bb1ef5e921c3064bbccc97d2f04f2f8 Mon Sep 17 00:00:00 2001 From: snow212-cn Date: Thu, 7 Jun 2018 22:34:19 +0800 Subject: [PATCH 01/11] Update object.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 这两段不知所云的英文插进代码段要干什么 --- docs/object.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/object.md b/docs/object.md index 1ca5a90..a1c2bdc 100644 --- a/docs/object.md +++ b/docs/object.md @@ -1426,8 +1426,6 @@ let newVersion = { ```javascript let aWithDefaults = { x: 1, y: 2, ...a }; // 等同于 - even if property keys don’t clash, because objects record insertion order: - let aWithDefaults = Object.assign({}, { x: 1, y: 2 }, a); // 等同于 let aWithDefaults = Object.assign({ x: 1, y: 2 }, a); @@ -1447,8 +1445,6 @@ const obj = { ```javascript {...{}, a: 1} // { a: 1 } - even if property keys don’t clash, because objects record insertion order: - ``` 如果扩展运算符的参数是`null`或`undefined`,这两个值会被忽略,不会报错。 From e4351e2a70cff6ff58337fd313b11875d3eba2cc Mon Sep 17 00:00:00 2001 From: favefan Date: Thu, 21 Jun 2018 09:28:48 +0800 Subject: [PATCH 02/11] word change. --- docs/let.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/let.md b/docs/let.md index 1120229..026b8ae 100644 --- a/docs/let.md +++ b/docs/let.md @@ -591,7 +591,7 @@ ES5 的顶层对象,本身也是一个问题,因为它在各种实现里面 - 全局环境中,`this`会返回顶层对象。但是,Node 模块和 ES6 模块中,`this`返回的是当前模块。 - 函数里面的`this`,如果函数不是作为对象的方法运行,而是单纯作为函数运行,`this`会指向顶层对象。但是,严格模式下,这时`this`会返回`undefined`。 -- 不管是严格模式,还是普通模式,`new Function('return this')()`,总是会返回全局对象。但是,如果浏览器用了 CSP(Content Security Policy,内容安全政策),那么`eval`、`new Function`这些方法都可能无法使用。 +- 不管是严格模式,还是普通模式,`new Function('return this')()`,总是会返回全局对象。但是,如果浏览器用了 CSP(Content Security Policy,内容安全策略),那么`eval`、`new Function`这些方法都可能无法使用。 综上所述,很难找到一种方法,可以在所有情况下,都取到顶层对象。下面是两种勉强可以使用的方法。 From 19e1974afe27c5b1ab192470618e1d2a989c3078 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 21 Jun 2018 16:40:25 +0800 Subject: [PATCH 03/11] docs: edit class-extends --- docs/class-extends.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/class-extends.md b/docs/class-extends.md index a81df72..3d39842 100644 --- a/docs/class-extends.md +++ b/docs/class-extends.md @@ -713,7 +713,7 @@ function mix(...mixins) { class Mix {} for (let mixin of mixins) { - copyProperties(Mix, mixin); // 拷贝实例属性 + copyProperties(Mix.prototype, new mixin()); // 拷贝实例属性 copyProperties(Mix.prototype, mixin.prototype); // 拷贝原型属性 } From 83bad90346c8c2486d8fa844bd7a0463757428bf Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 21 Jun 2018 16:57:09 +0800 Subject: [PATCH 04/11] docs: edit class-extends --- docs/class-extends.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/class-extends.md b/docs/class-extends.md index 3d39842..867868d 100644 --- a/docs/class-extends.md +++ b/docs/class-extends.md @@ -713,8 +713,8 @@ function mix(...mixins) { class Mix {} for (let mixin of mixins) { - copyProperties(Mix.prototype, new mixin()); // 拷贝实例属性 - copyProperties(Mix.prototype, mixin.prototype); // 拷贝原型属性 + copyProperties(Mix.prototype, mixin); // 拷贝实例属性 + copyProperties(Mix.prototype, Object.getPrototypeOf(mixin)); // 拷贝原型属性 } return Mix; From 3c44084f4b2e318fcbec77b7191b1f2412726c47 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Mon, 25 Jun 2018 12:26:32 +0800 Subject: [PATCH 05/11] =?UTF-8?q?docs(class-extends):=20=E5=88=A0=E9=99=A4?= =?UTF-8?q?=20class=20X=20extends=20null=20=E7=9A=84=E8=AE=A8=E8=AE=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/class-extends.md | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/docs/class-extends.md b/docs/class-extends.md index 867868d..098b81b 100644 --- a/docs/class-extends.md +++ b/docs/class-extends.md @@ -452,8 +452,6 @@ Object.create(A.prototype); B.prototype.__proto__ = A.prototype; ``` -### extends 的继承目标 - `extends`关键字后面可以跟多种类型的值。 ```javascript @@ -463,9 +461,7 @@ class B extends A { 上面代码的`A`,只要是一个有`prototype`属性的函数,就能被`B`继承。由于函数都有`prototype`属性(除了`Function.prototype`函数),因此`A`可以是任意函数。 -下面,讨论三种特殊情况。 - -第一种特殊情况,子类继承`Object`类。 +下面,讨论两种情况。第一种,子类继承`Object`类。 ```javascript class A extends Object { @@ -477,7 +473,7 @@ A.prototype.__proto__ === Object.prototype // true 这种情况下,`A`其实就是构造函数`Object`的复制,`A`的实例就是`Object`的实例。 -第二种特殊情况,不存在任何继承。 +第二种情况,不存在任何继承。 ```javascript class A { @@ -489,24 +485,6 @@ A.prototype.__proto__ === Object.prototype // true 这种情况下,`A`作为一个基类(即不存在任何继承),就是一个普通函数,所以直接继承`Function.prototype`。但是,`A`调用后返回一个空对象(即`Object`实例),所以`A.prototype.__proto__`指向构造函数(`Object`)的`prototype`属性。 -第三种特殊情况,子类继承`null`。 - -```javascript -class A extends null { -} - -A.__proto__ === Function.prototype // true -A.prototype.__proto__ === undefined // true -``` - -这种情况与第二种情况非常像。`A`也是一个普通函数,所以直接继承`Function.prototype`。但是,`A`调用后返回的对象不继承任何方法,所以它的`__proto__`指向`undefined`,即实质上执行了下面的代码。 - -```javascript -class C extends null { - constructor() { return Object.create(null); } -} -``` - ### 实例的 \_\_proto\_\_ 属性 子类实例的`__proto__`属性的`__proto__`属性,指向父类实例的`__proto__`属性。也就是说,子类的原型的原型,是父类的原型。 @@ -714,7 +692,7 @@ function mix(...mixins) { for (let mixin of mixins) { copyProperties(Mix.prototype, mixin); // 拷贝实例属性 - copyProperties(Mix.prototype, Object.getPrototypeOf(mixin)); // 拷贝原型属性 + copyProperties(Mix.prototype, Reflect.getPrototypeOf(mixin)); // 拷贝原型属性 } return Mix; From e85f4dd15a17713d076524f8f131f7f0ddb04450 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Mon, 2 Jul 2018 14:16:27 +0800 Subject: [PATCH 06/11] docs(iterator): edit return() #708 --- docs/iterator.md | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/docs/iterator.md b/docs/iterator.md index a05753f..a809106 100644 --- a/docs/iterator.md +++ b/docs/iterator.md @@ -475,7 +475,7 @@ for (let x of obj) { 遍历器对象除了具有`next`方法,还可以具有`return`方法和`throw`方法。如果你自己写遍历器对象生成函数,那么`next`方法是必须部署的,`return`方法和`throw`方法是否部署是可选的。 -`return`方法的使用场合是,如果`for...of`循环提前退出(通常是因为出错,或者有`break`语句或`continue`语句),就会调用`return`方法。如果一个对象在完成遍历前,需要清理或释放资源,就可以部署`return`方法。 +`return`方法的使用场合是,如果`for...of`循环提前退出(通常是因为出错,或者有`break`语句),就会调用`return`方法。如果一个对象在完成遍历前,需要清理或释放资源,就可以部署`return`方法。 ```javascript function readLinesSync(file) { @@ -495,7 +495,7 @@ function readLinesSync(file) { } ``` -上面代码中,函数`readLinesSync`接受一个文件对象作为参数,返回一个遍历器对象,其中除了`next`方法,还部署了`return`方法。下面的三种情况,都会触发执行`return`方法。 +上面代码中,函数`readLinesSync`接受一个文件对象作为参数,返回一个遍历器对象,其中除了`next`方法,还部署了`return`方法。下面的两种情况,都会触发执行`return`方法。 ```javascript // 情况一 @@ -505,12 +505,6 @@ for (let line of readLinesSync(fileName)) { } // 情况二 -for (let line of readLinesSync(fileName)) { - console.log(line); - continue; -} - -// 情况三 for (let line of readLinesSync(fileName)) { console.log(line); throw new Error(); From efafe678d1fe16c9a405a7b328941d33a460ac53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Shaoyao=C2=B7=E7=90=9A?= Date: Wed, 4 Jul 2018 08:11:26 +0200 Subject: [PATCH 07/11] Update module.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修正描述 --- docs/module.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/module.md b/docs/module.md index f9ddc8e..f27c0f8 100644 --- a/docs/module.md +++ b/docs/module.md @@ -453,7 +453,7 @@ export default 42; export 42; ``` -上面代码中,后一句报错是因为没有指定对外的接口,而前一句指定外对接口为`default`。 +上面代码中,后一句报错是因为没有指定对外的接口,而前一句指定对外接口为`default`。 有了`export default`命令,输入模块时就非常直观了,以输入 lodash 模块为例。 @@ -643,7 +643,7 @@ export {users} from './users'; ```javascript // script.js -import {db, users} from './index'; +import {db, users} from './constants/index'; ``` ## import() From d4c8df426ab9942a745584998754fe0ae114e44d Mon Sep 17 00:00:00 2001 From: ruanyf Date: Fri, 6 Jul 2018 10:32:43 +0800 Subject: [PATCH 08/11] docs(class-extends): fix super() #711 --- docs/class-extends.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/class-extends.md b/docs/class-extends.md index 098b81b..617dfaf 100644 --- a/docs/class-extends.md +++ b/docs/class-extends.md @@ -44,7 +44,7 @@ let cp = new ColorPoint(); // ReferenceError 上面代码中,`ColorPoint`继承了父类`Point`,但是它的构造函数没有调用`super`方法,导致新建实例时报错。 -ES5 的继承,实质是先创造子类的实例对象`this`,然后再将父类的方法添加到`this`上面(`Parent.apply(this)`)。ES6 的继承机制完全不同,实质是先创造父类的实例对象`this`(所以必须先调用`super`方法),然后再用子类的构造函数修改`this`。 +ES5 的继承,实质是先创造子类的实例对象`this`,然后再将父类的方法添加到`this`上面(`Parent.apply(this)`)。ES6 的继承机制完全不同,实质是先将父类实例对象的属性和方法,加到`this`上面(所以必须先调用`super`方法),然后再用子类的构造函数修改`this`。 如果子类没有定义`constructor`方法,这个方法会被默认添加,代码如下。也就是说,不管有没有显式定义,任何一个子类都有`constructor`方法。 @@ -60,7 +60,7 @@ class ColorPoint extends Point { } ``` -另一个需要注意的地方是,在子类的构造函数中,只有调用`super`之后,才可以使用`this`关键字,否则会报错。这是因为子类实例的构建,是基于对父类实例加工,只有`super`方法才能返回父类实例。 +另一个需要注意的地方是,在子类的构造函数中,只有调用`super`之后,才可以使用`this`关键字,否则会报错。这是因为子类实例的构建,基于父类实例,只有`super`方法才能调用父类实例。 ```javascript class Point { From a46664f54abb9742fe22cb31285b1cac8c7929a9 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Fri, 6 Jul 2018 10:36:01 +0800 Subject: [PATCH 09/11] docs(iterator): fix return() --- docs/iterator.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/iterator.md b/docs/iterator.md index a809106..a39352c 100644 --- a/docs/iterator.md +++ b/docs/iterator.md @@ -511,7 +511,7 @@ for (let line of readLinesSync(fileName)) { } ``` -上面代码中,情况一输出文件的第一行以后,就会执行`return`方法,关闭这个文件;情况二输出所有行以后,执行`return`方法,关闭该文件;情况三会在执行`return`方法关闭文件之后,再抛出错误。 +上面代码中,情况一输出文件的第一行以后,就会执行`return`方法,关闭这个文件;情况二会在执行`return`方法关闭文件之后,再抛出错误。 注意,`return`方法必须返回一个对象,这是 Generator 规格决定的。 From 94024df0f113114bf7ad9e5293fa2d5c8da19f77 Mon Sep 17 00:00:00 2001 From: hanty <841609790@qq.com> Date: Wed, 11 Jul 2018 14:46:51 +0800 Subject: [PATCH 10/11] Update async.md --- docs/async.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/async.md b/docs/async.md index 02c174e..b3931fa 100644 --- a/docs/async.md +++ b/docs/async.md @@ -722,9 +722,10 @@ async function f() { 注意,异步遍历器的`next`方法是可以连续调用的,不必等到上一步产生的 Promise 对象`resolve`以后再调用。这种情况下,`next`方法会累积起来,自动按照每一步的顺序运行下去。下面是一个例子,把所有的`next`方法放在`Promise.all`方法里面。 ```javascript -const asyncGenObj = createAsyncIterable(['a', 'b']); +const asyncIterable = createAsyncIterable(['a', 'b']); +const asyncIterator = asyncIterable[Symbol.asyncIterator](); const [{value: v1}, {value: v2}] = await Promise.all([ - asyncGenObj.next(), asyncGenObj.next() + asyncIterator.next(), asyncIterator.next() ]); console.log(v1, v2); // a b From 0fe548fd2b7c8a6a073104a2c52faa75fff41f86 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 17 Jul 2018 12:25:16 +0800 Subject: [PATCH 11/11] docs(let): edit const #720 --- docs/let.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/let.md b/docs/let.md index 026b8ae..a8b4dde 100644 --- a/docs/let.md +++ b/docs/let.md @@ -494,7 +494,7 @@ const age = 30; ### 本质 -`const`实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指针,`const`只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。 +`const`实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,`const`只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。 ```javascript const foo = {};