From dfd5c0ac0e0039dabf91999393675adbdce385c4 Mon Sep 17 00:00:00 2001 From: shenzhim Date: Thu, 31 May 2018 19:30:36 +0800 Subject: [PATCH 001/446] =?UTF-8?q?@std/esm=20=E5=B7=B2=E7=BB=8Fdeprecated?= =?UTF-8?q?=EF=BC=8C=E6=94=B9=E4=B8=BAesm?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/async.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/async.md b/docs/async.md index b411cb6c5..02c174e3d 100644 --- a/docs/async.md +++ b/docs/async.md @@ -460,7 +460,7 @@ async function dbFuc(db) { } ``` -目前,[`@std/esm`](https://www.npmjs.com/package/@std/esm)模块加载器支持顶层`await`,即`await`命令可以不放在 async 函数里面,直接使用。 +目前,[`esm`](https://www.npmjs.com/package/esm)模块加载器支持顶层`await`,即`await`命令可以不放在 async 函数里面,直接使用。 ```javascript // async 函数的写法 @@ -476,7 +476,7 @@ const res = await fetch('google.com'); console.log(await res.text()); ``` -上面代码中,第二种写法的脚本必须使用`@std/esm`加载器,才会生效。 +上面代码中,第二种写法的脚本必须使用`esm`加载器,才会生效。 ## async 函数的实现原理 From 42e06a84d9ef75f7547ff4584802494c55d3c82a Mon Sep 17 00:00:00 2001 From: ruanyf Date: Mon, 4 Jun 2018 11:12:30 +0800 Subject: [PATCH 002/446] docs(reference): edit reference --- docs/proxy.md | 4 ++-- docs/reference.md | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/proxy.md b/docs/proxy.md index d7bfbfe3e..6120bbae3 100644 --- a/docs/proxy.md +++ b/docs/proxy.md @@ -303,7 +303,7 @@ d.a === d // true 上面代码中,`d`对象本身没有`a`属性,所以读取`d.a`的时候,会去`d`的原型`proxy`对象找。这时,`receiver`就指向`d`,代表原始的读操作所在的那个对象。 -如果一个属性不可配置(configurable)和不可写(writable),则该属性不能被代理,通过 Proxy 对象访问该属性会报错。 +如果一个属性不可配置(configurable)且不可写(writable),则 Proxy 不能修改该属性,否则通过 Proxy 对象访问该属性会报错。 ```javascript const target = Object.defineProperties({}, { @@ -420,7 +420,7 @@ myObj.foo === myObj // true 上面代码中,设置`myObj.foo`属性的值时,`myObj`并没有`foo`属性,因此引擎会到`myObj`的原型链去找`foo`属性。`myObj`的原型对象`proxy`是一个 Proxy 实例,设置它的`foo`属性会触发`set`方法。这时,第四个参数`receiver`就指向原始赋值行为所在的对象`myObj`。 -注意,如果目标对象自身的某个属性,不可写或不可配置,那么`set`方法将不起作用。 +注意,如果目标对象自身的某个属性,不可写且不可配置,那么`set`方法将不起作用。 ```javascript const obj = {}; diff --git a/docs/reference.md b/docs/reference.md index 795c61ee2..9d2330fe1 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -140,6 +140,7 @@ ## Promise 对象 - Jake Archibald, [JavaScript Promises: There and back again](http://www.html5rocks.com/en/tutorials/es6/promises/) +- Jake Archibald, [Tasks, microtasks, queues and schedules](https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/) - Tilde, [rsvp.js](https://github.com/tildeio/rsvp.js) - Sandeep Panda, [An Overview of JavaScript Promises](http://www.sitepoint.com/overview-javascript-promises/): ES6 Promise 入门介绍 - Dave Atchley, [ES6 Promises](http://www.datchley.name/es6-promises/): Promise 的语法介绍 From 688ca45e6fb0ad3e0d3c5904dde3ccf486fc7a37 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 5 Jun 2018 13:33:35 +0800 Subject: [PATCH 003/446] docs(Reflect): fix Reflect.setPrototypeOf #693 --- docs/reflect.md | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/docs/reflect.md b/docs/reflect.md index ff3fd579b..7ee1dbcfd 100644 --- a/docs/reflect.md +++ b/docs/reflect.md @@ -313,16 +313,27 @@ Reflect.getPrototypeOf(1) // 报错 ### Reflect.setPrototypeOf(obj, newProto) -`Reflect.setPrototypeOf`方法用于设置对象的`__proto__`属性,返回第一个参数对象,对应`Object.setPrototypeOf(obj, newProto)`。 +`Reflect.setPrototypeOf`方法用于设置目标对象的原型(prototype),对应`Object.setPrototypeOf(obj, newProto)`方法。它返回一个布尔值,表示是否设置成功。 ```javascript -const myObj = new FancyThing(); +const myObj = {}; // 旧写法 -Object.setPrototypeOf(myObj, OtherThing.prototype); +Object.setPrototypeOf(myObj, Array.prototype); // 新写法 -Reflect.setPrototypeOf(myObj, OtherThing.prototype); +Reflect.setPrototypeOf(myObj, Array.prototype); + +myObj.length // 0 +``` + +如果无法设置目标对象的原型(比如,目标对象禁止扩展),`Reflect.setPrototypeOf`方法返回`false`。 + +```javascript +Reflect.setPrototypeOf({}, null) +// true +Reflect.setPrototypeOf(Object.freeze({}), null) +// false ``` 如果第一个参数不是对象,`Object.setPrototypeOf`会返回第一个参数本身,而`Reflect.setPrototypeOf`会报错。 From cdc7e48d939cab5a0027664b65bcd228ede46ee8 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 5 Jun 2018 16:48:43 +0800 Subject: [PATCH 004/446] docs(array): edit spread operator #694 --- docs/array.md | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/docs/array.md b/docs/array.md index 30137c236..7f6fd379f 100644 --- a/docs/array.md +++ b/docs/array.md @@ -163,24 +163,34 @@ const [...a2] = a1; 扩展运算符提供了数组合并的新写法。 ```javascript -// ES5 -[1, 2].concat(more) -// ES6 -[1, 2, ...more] - -var arr1 = ['a', 'b']; -var arr2 = ['c']; -var arr3 = ['d', 'e']; +const arr1 = ['a', 'b']; +const arr2 = ['c']; +const arr3 = ['d', 'e']; -// ES5的合并数组 +// ES5 的合并数组 arr1.concat(arr2, arr3); // [ 'a', 'b', 'c', 'd', 'e' ] -// ES6的合并数组 +// ES6 的合并数组 [...arr1, ...arr2, ...arr3] // [ 'a', 'b', 'c', 'd', 'e' ] ``` +不过,这两种方法都是浅拷贝,使用的时候需要注意。 + +```javascript +const a1 = [{ foo: 1 }]; +const a2 = [{ bar: 2 }]; + +const a3 = a1.concat(a2); +const a4 = [...a1, ...a2]; + +a3[0] === a1[0] // true +a4[0] === a1[0] // true +``` + +上面代码中,`a3`和`a4`是用两种不同方法合并而成的新数组,但是它们的成员都是对原数组成员的引用,这就是浅拷贝。如果修改了原数组的成员,会同步反映到新数组。 + **(3)与解构赋值结合** 扩展运算符可以与解构赋值结合起来,用于生成数组。 From 6583714f3bb1ef5e921c3064bbccc97d2f04f2f8 Mon Sep 17 00:00:00 2001 From: snow212-cn Date: Thu, 7 Jun 2018 22:34:19 +0800 Subject: [PATCH 005/446] 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 1ca5a90cf..a1c2bdc2c 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 006/446] word change. --- docs/let.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/let.md b/docs/let.md index 112022907..026b8aefb 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 007/446] 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 a81df72a9..3d39842f5 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 008/446] 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 3d39842f5..867868d0c 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 009/446] =?UTF-8?q?docs(class-extends):=20=E5=88=A0?= =?UTF-8?q?=E9=99=A4=20class=20X=20extends=20null=20=E7=9A=84=E8=AE=A8?= =?UTF-8?q?=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 867868d0c..098b81bdc 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 010/446] 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 a05753f63..a8091062f 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 011/446] 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 f9ddc8ed4..f27c0f87f 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 012/446] 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 098b81bdc..617dfaf05 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 013/446] 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 a8091062f..a39352c4a 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 014/446] 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 02c174e3d..b3931fa28 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 015/446] 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 026b8aefb..a8b4ddec6 100644 --- a/docs/let.md +++ b/docs/let.md @@ -494,7 +494,7 @@ const age = 30; ### 本质 -`const`实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指针,`const`只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。 +`const`实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,`const`只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。 ```javascript const foo = {}; From 420a9f76f8651a511c73e0a09cba6cef80afba93 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 17 Jul 2018 21:42:52 +0800 Subject: [PATCH 016/446] docs(let): fix const #720 --- docs/let.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/let.md b/docs/let.md index 112022907..a2dae6fa6 100644 --- a/docs/let.md +++ b/docs/let.md @@ -494,7 +494,7 @@ const age = 30; ### 本质 -`const`实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指针,`const`只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。 +`const`实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,`const`只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。 ```javascript const foo = {}; From 3034d8e4ed0e29a6bcd3c1e5699536a351037c7f Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 24 Jul 2018 11:06:49 +0800 Subject: [PATCH 017/446] refact: cancel inline JS codes --- config.js | 1 + index.html | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/config.js b/config.js index 2ea5eb093..f0c3ad930 100644 --- a/config.js +++ b/config.js @@ -24,3 +24,4 @@ function addConfig(obj, conf) { }); } +ditto.run(); diff --git a/index.html b/index.html index 66a636001..98936328a 100644 --- a/index.html +++ b/index.html @@ -28,9 +28,6 @@
-