Skip to content

Commit

Permalink
docs(let): fix const #720
Browse files Browse the repository at this point in the history
  • Loading branch information
ruanyf committed Jul 17, 2018
2 parents 420a9f7 + 0fe548f commit 86b5a9c
Show file tree
Hide file tree
Showing 6 changed files with 15 additions and 46 deletions.
5 changes: 3 additions & 2 deletions docs/async.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
34 changes: 6 additions & 28 deletions docs/class-extends.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`方法。

Expand All @@ -60,7 +60,7 @@ class ColorPoint extends Point {
}
```

另一个需要注意的地方是,在子类的构造函数中,只有调用`super`之后,才可以使用`this`关键字,否则会报错。这是因为子类实例的构建,是基于对父类实例加工,只有`super`方法才能返回父类实例
另一个需要注意的地方是,在子类的构造函数中,只有调用`super`之后,才可以使用`this`关键字,否则会报错。这是因为子类实例的构建,基于父类实例,只有`super`方法才能调用父类实例

```javascript
class Point {
Expand Down Expand Up @@ -452,8 +452,6 @@ Object.create(A.prototype);
B.prototype.__proto__ = A.prototype;
```

### extends 的继承目标

`extends`关键字后面可以跟多种类型的值。

```javascript
Expand All @@ -463,9 +461,7 @@ class B extends A {

上面代码的`A`,只要是一个有`prototype`属性的函数,就能被`B`继承。由于函数都有`prototype`属性(除了`Function.prototype`函数),因此`A`可以是任意函数。

下面,讨论三种特殊情况。

第一种特殊情况,子类继承`Object`类。
下面,讨论两种情况。第一种,子类继承`Object`类。

```javascript
class A extends Object {
Expand All @@ -477,7 +473,7 @@ A.prototype.__proto__ === Object.prototype // true

这种情况下,`A`其实就是构造函数`Object`的复制,`A`的实例就是`Object`的实例。

第二种特殊情况,不存在任何继承。
第二种情况,不存在任何继承。

```javascript
class A {
Expand All @@ -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__`属性。也就是说,子类的原型的原型,是父类的原型。
Expand Down Expand Up @@ -713,8 +691,8 @@ function mix(...mixins) {
class Mix {}

for (let mixin of mixins) {
copyProperties(Mix, mixin); // 拷贝实例属性
copyProperties(Mix.prototype, mixin.prototype); // 拷贝原型属性
copyProperties(Mix.prototype, mixin); // 拷贝实例属性
copyProperties(Mix.prototype, Reflect.getPrototypeOf(mixin)); // 拷贝原型属性
}

return Mix;
Expand Down
12 changes: 3 additions & 9 deletions docs/iterator.md
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -495,7 +495,7 @@ function readLinesSync(file) {
}
```

上面代码中,函数`readLinesSync`接受一个文件对象作为参数,返回一个遍历器对象,其中除了`next`方法,还部署了`return`方法。下面的三种情况,都会触发执行`return`方法。
上面代码中,函数`readLinesSync`接受一个文件对象作为参数,返回一个遍历器对象,其中除了`next`方法,还部署了`return`方法。下面的两种情况,都会触发执行`return`方法。

```javascript
// 情况一
Expand All @@ -505,19 +505,13 @@ 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();
}
```

上面代码中,情况一输出文件的第一行以后,就会执行`return`方法,关闭这个文件;情况二输出所有行以后,执行`return`方法,关闭该文件;情况三会在执行`return`方法关闭文件之后,再抛出错误。
上面代码中,情况一输出文件的第一行以后,就会执行`return`方法,关闭这个文件;情况二会在执行`return`方法关闭文件之后,再抛出错误。

注意,`return`方法必须返回一个对象,这是 Generator 规格决定的。

Expand Down
2 changes: 1 addition & 1 deletion docs/let.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`这些方法都可能无法使用。

综上所述,很难找到一种方法,可以在所有情况下,都取到顶层对象。下面是两种勉强可以使用的方法。

Expand Down
4 changes: 2 additions & 2 deletions docs/module.md
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ export default 42;
export 42;
```

上面代码中,后一句报错是因为没有指定对外的接口,而前一句指定外对接口为`default`
上面代码中,后一句报错是因为没有指定对外的接口,而前一句指定对外接口为`default`

有了`export default`命令,输入模块时就非常直观了,以输入 lodash 模块为例。

Expand Down Expand Up @@ -643,7 +643,7 @@ export {users} from './users';

```javascript
// script.js
import {db, users} from './index';
import {db, users} from './constants/index';
```

## import()
Expand Down
4 changes: 0 additions & 4 deletions docs/object.md
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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`,这两个值会被忽略,不会报错。
Expand Down

0 comments on commit 86b5a9c

Please sign in to comment.