From 88248d97c38a1f7bb1e9a4845bed23b9ab24091f Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 10 Oct 2017 08:14:56 +0800 Subject: [PATCH] docs(array): edit array/spread --- docs/array.md | 59 +++++++++++++++++++++++++++++++++++------------- docs/function.md | 4 ++-- docs/symbol.md | 8 +++---- 3 files changed, 49 insertions(+), 22 deletions(-) diff --git a/docs/array.md b/docs/array.md index 1858e6b..18bc0b3 100644 --- a/docs/array.md +++ b/docs/array.md @@ -120,7 +120,45 @@ new Date(...[2015, 1, 1]); ### 扩展运算符的应用 -**(1)合并数组** +**(1)复制数组** + +数组是复合的数据类型,直接复制的话,只是复制了指向底层数据结构的指针,而不是克隆一个全新的数组。 + +```javascript +const a1 = [1, 2]; +const a2 = a1; + +a2[0] = 2; +a1 // [2, 2] +``` + +上面代码中,`a2`并不是`a1`的克隆,而是指向同一份数据的另一个指针。修改`a2`,会直接导致`a1`的变化。 + +ES5 只能用变通方法来复制数组。 + +```javascript +const a1 = [1, 2]; +const a2 = a1.concat(); + +a2[0] = 2; +a1 // [1, 2] +``` + +上面代码中,`a1`会返回原数组的克隆,再修改`a2`就不会对`a1`产生影响。 + +扩展运算符提供了复制数组的简便写法。 + +```javascript +const a1 = [1, 2]; +// 写法一 +const a2 = [...a1]; +// 写法二 +const [...a2] = a1; +``` + +上面的两种写法,`a2`都是`a1`的克隆。 + +**(2)合并数组** 扩展运算符提供了数组合并的新写法。 @@ -143,7 +181,7 @@ arr1.concat(arr2, arr3); // [ 'a', 'b', 'c', 'd', 'e' ] ``` -**(2)与解构赋值结合** +**(3)与解构赋值结合** 扩展运算符可以与解构赋值结合起来,用于生成数组。 @@ -180,17 +218,6 @@ const [first, ...middle, last] = [1, 2, 3, 4, 5]; // 报错 ``` -**(3)函数的返回值** - -JavaScript 的函数只能返回一个值,如果需要返回多个值,只能返回数组或对象。扩展运算符提供了解决这个问题的一种变通方法。 - -```javascript -let dateFields = readDateFields(database); -let d = new Date(...dateFields); -``` - -上面代码从数据库取出一行数据,通过扩展运算符,直接将其传入构造函数`Date`。 - **(4)字符串** 扩展运算符还可以将字符串转为真正的数组。 @@ -200,14 +227,14 @@ let d = new Date(...dateFields); // [ "h", "e", "l", "l", "o" ] ``` -上面的写法,有一个重要的好处,那就是能够正确识别32位的Unicode字符。 +上面的写法,有一个重要的好处,那就是能够正确识别四个字节的 Unicode 字符。 ```javascript 'x\uD83D\uDE80y'.length // 4 [...'x\uD83D\uDE80y'].length // 3 ``` -上面代码的第一种写法,JavaScript会将32位Unicode字符,识别为2个字符,采用扩展运算符就没有这个问题。因此,正确返回字符串长度的函数,可以像下面这样写。 +上面代码的第一种写法,JavaScript 会将四个字节的 Unicode 字符,识别为2个字符,采用扩展运算符就没有这个问题。因此,正确返回字符串长度的函数,可以像下面这样写。 ```javascript function length(str) { @@ -217,7 +244,7 @@ function length(str) { length('x\uD83D\uDE80y') // 3 ``` -凡是涉及到操作32位 Unicode 字符的函数,都有这个问题。因此,最好都用扩展运算符改写。 +凡是涉及到操作四个字节的 Unicode 字符的函数,都有这个问题。因此,最好都用扩展运算符改写。 ```javascript let str = 'x\uD83D\uDE80y'; diff --git a/docs/function.md b/docs/function.md index b52ea7a..3472048 100644 --- a/docs/function.md +++ b/docs/function.md @@ -139,7 +139,7 @@ fetch('http://example.com') 上面代码中,如果函数`fetch`的第二个参数是一个对象,就可以为它的三个属性设置默认值。这种写法不能省略第二个参数,如果结合函数参数的默认值,就可以省略第二个参数。这时,就出现了双重默认值。 ```javascript -function fetch(url, { method = 'GET' } = {}) { +function fetch(url, { body = '', method = 'GET', headers = {} } = {}) { console.log(method); } @@ -149,7 +149,7 @@ fetch('http://example.com') 上面代码中,函数`fetch`没有第二个参数时,函数参数的默认值就会生效,然后才是解构赋值的默认值生效,变量`method`才会取到默认值`GET`。 -再请问下面两种写法有什么差别? +作为练习,请问下面两种写法有什么差别? ```javascript // 写法一 diff --git a/docs/symbol.md b/docs/symbol.md index ac45708..567368a 100644 --- a/docs/symbol.md +++ b/docs/symbol.md @@ -341,7 +341,7 @@ Object.getOwnPropertySymbols(x) // [Symbol(size)] ## Symbol.for(),Symbol.keyFor() -有时,我们希望重新使用同一个Symbol值,`Symbol.for`方法可以做到这一点。它接受一个字符串作为参数,然后搜索有没有以该参数作为名称的Symbol值。如果有,就返回这个Symbol值,否则就新建并返回一个以该字符串为名称的Symbol值。 +有时,我们希望重新使用同一个 Symbol 值,`Symbol.for`方法可以做到这一点。它接受一个字符串作为参数,然后搜索有没有以该参数作为名称的Symbol值。如果有,就返回这个 Symbol 值,否则就新建并返回一个以该字符串为名称的 Symbol 值。 ```javascript let s1 = Symbol.for('foo'); @@ -352,7 +352,7 @@ s1 === s2 // true 上面代码中,`s1`和`s2`都是 Symbol 值,但是它们都是同样参数的`Symbol.for`方法生成的,所以实际上是同一个值。 -`Symbol.for()`与`Symbol()`这两种写法,都会生成新的Symbol。它们的区别是,前者会被登记在全局环境中供搜索,后者不会。`Symbol.for()`不会每次调用就返回一个新的 Symbol 类型的值,而是会先检查给定的`key`是否已经存在,如果不存在才会新建一个值。比如,如果你调用`Symbol.for("cat")`30次,每次都会返回同一个 Symbol 值,但是调用`Symbol("cat")`30次,会返回30个不同的Symbol值。 +`Symbol.for()`与`Symbol()`这两种写法,都会生成新的 Symbol。它们的区别是,前者会被登记在全局环境中供搜索,后者不会。`Symbol.for()`不会每次调用就返回一个新的 Symbol 类型的值,而是会先检查给定的`key`是否已经存在,如果不存在才会新建一个值。比如,如果你调用`Symbol.for("cat")`30次,每次都会返回同一个 Symbol 值,但是调用`Symbol("cat")`30次,会返回30个不同的 Symbol 值。 ```javascript Symbol.for("bar") === Symbol.for("bar") @@ -374,9 +374,9 @@ let s2 = Symbol("foo"); Symbol.keyFor(s2) // undefined ``` -上面代码中,变量`s2`属于未登记的Symbol值,所以返回`undefined`。 +上面代码中,变量`s2`属于未登记的 Symbol 值,所以返回`undefined`。 -需要注意的是,`Symbol.for`为Symbol值登记的名字,是全局环境的,可以在不同的 iframe 或 service worker 中取到同一个值。 +需要注意的是,`Symbol.for`为 Symbol 值登记的名字,是全局环境的,可以在不同的 iframe 或 service worker 中取到同一个值。 ```javascript iframe = document.createElement('iframe');