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:
parent
a782099ff2
commit
88248d97c3
@ -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' ]
|
// [ '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)字符串**
|
**(4)字符串**
|
||||||
|
|
||||||
扩展运算符还可以将字符串转为真正的数组。
|
扩展运算符还可以将字符串转为真正的数组。
|
||||||
@ -200,14 +227,14 @@ let d = new Date(...dateFields);
|
|||||||
// [ "h", "e", "l", "l", "o" ]
|
// [ "h", "e", "l", "l", "o" ]
|
||||||
```
|
```
|
||||||
|
|
||||||
上面的写法,有一个重要的好处,那就是能够正确识别32位的Unicode字符。
|
上面的写法,有一个重要的好处,那就是能够正确识别四个字节的 Unicode 字符。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
'x\uD83D\uDE80y'.length // 4
|
'x\uD83D\uDE80y'.length // 4
|
||||||
[...'x\uD83D\uDE80y'].length // 3
|
[...'x\uD83D\uDE80y'].length // 3
|
||||||
```
|
```
|
||||||
|
|
||||||
上面代码的第一种写法,JavaScript会将32位Unicode字符,识别为2个字符,采用扩展运算符就没有这个问题。因此,正确返回字符串长度的函数,可以像下面这样写。
|
上面代码的第一种写法,JavaScript 会将四个字节的 Unicode 字符,识别为2个字符,采用扩展运算符就没有这个问题。因此,正确返回字符串长度的函数,可以像下面这样写。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
function length(str) {
|
function length(str) {
|
||||||
@ -217,7 +244,7 @@ function length(str) {
|
|||||||
length('x\uD83D\uDE80y') // 3
|
length('x\uD83D\uDE80y') // 3
|
||||||
```
|
```
|
||||||
|
|
||||||
凡是涉及到操作32位 Unicode 字符的函数,都有这个问题。因此,最好都用扩展运算符改写。
|
凡是涉及到操作四个字节的 Unicode 字符的函数,都有这个问题。因此,最好都用扩展运算符改写。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
let str = 'x\uD83D\uDE80y';
|
let str = 'x\uD83D\uDE80y';
|
||||||
|
@ -139,7 +139,7 @@ fetch('http://example.com')
|
|||||||
上面代码中,如果函数`fetch`的第二个参数是一个对象,就可以为它的三个属性设置默认值。这种写法不能省略第二个参数,如果结合函数参数的默认值,就可以省略第二个参数。这时,就出现了双重默认值。
|
上面代码中,如果函数`fetch`的第二个参数是一个对象,就可以为它的三个属性设置默认值。这种写法不能省略第二个参数,如果结合函数参数的默认值,就可以省略第二个参数。这时,就出现了双重默认值。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
function fetch(url, { method = 'GET' } = {}) {
|
function fetch(url, { body = '', method = 'GET', headers = {} } = {}) {
|
||||||
console.log(method);
|
console.log(method);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,7 +149,7 @@ fetch('http://example.com')
|
|||||||
|
|
||||||
上面代码中,函数`fetch`没有第二个参数时,函数参数的默认值就会生效,然后才是解构赋值的默认值生效,变量`method`才会取到默认值`GET`。
|
上面代码中,函数`fetch`没有第二个参数时,函数参数的默认值就会生效,然后才是解构赋值的默认值生效,变量`method`才会取到默认值`GET`。
|
||||||
|
|
||||||
再请问下面两种写法有什么差别?
|
作为练习,请问下面两种写法有什么差别?
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
// 写法一
|
// 写法一
|
||||||
|
@ -341,7 +341,7 @@ Object.getOwnPropertySymbols(x) // [Symbol(size)]
|
|||||||
|
|
||||||
## Symbol.for(),Symbol.keyFor()
|
## Symbol.for(),Symbol.keyFor()
|
||||||
|
|
||||||
有时,我们希望重新使用同一个Symbol值,`Symbol.for`方法可以做到这一点。它接受一个字符串作为参数,然后搜索有没有以该参数作为名称的Symbol值。如果有,就返回这个Symbol值,否则就新建并返回一个以该字符串为名称的Symbol值。
|
有时,我们希望重新使用同一个 Symbol 值,`Symbol.for`方法可以做到这一点。它接受一个字符串作为参数,然后搜索有没有以该参数作为名称的Symbol值。如果有,就返回这个 Symbol 值,否则就新建并返回一个以该字符串为名称的 Symbol 值。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
let s1 = Symbol.for('foo');
|
let s1 = Symbol.for('foo');
|
||||||
@ -352,7 +352,7 @@ s1 === s2 // true
|
|||||||
|
|
||||||
上面代码中,`s1`和`s2`都是 Symbol 值,但是它们都是同样参数的`Symbol.for`方法生成的,所以实际上是同一个值。
|
上面代码中,`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
|
```javascript
|
||||||
Symbol.for("bar") === Symbol.for("bar")
|
Symbol.for("bar") === Symbol.for("bar")
|
||||||
@ -374,9 +374,9 @@ let s2 = Symbol("foo");
|
|||||||
Symbol.keyFor(s2) // undefined
|
Symbol.keyFor(s2) // undefined
|
||||||
```
|
```
|
||||||
|
|
||||||
上面代码中,变量`s2`属于未登记的Symbol值,所以返回`undefined`。
|
上面代码中,变量`s2`属于未登记的 Symbol 值,所以返回`undefined`。
|
||||||
|
|
||||||
需要注意的是,`Symbol.for`为Symbol值登记的名字,是全局环境的,可以在不同的 iframe 或 service worker 中取到同一个值。
|
需要注意的是,`Symbol.for`为 Symbol 值登记的名字,是全局环境的,可以在不同的 iframe 或 service worker 中取到同一个值。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
iframe = document.createElement('iframe');
|
iframe = document.createElement('iframe');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user