1
0
mirror of https://github.com/ruanyf/es6tutorial.git synced 2025-05-24 18:32:22 +00:00

docs(array): edit array/spread

This commit is contained in:
ruanyf 2017-10-10 08:14:56 +08:00
parent a782099ff2
commit 88248d97c3
3 changed files with 49 additions and 22 deletions

View File

@ -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';

View File

@ -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
// 写法一

View File

@ -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');