freeCodeCamp/guide/chinese/javascript/spread-syntax/index.md

147 lines
4.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

---
title: Spread syntax
localeTitle: 传播语法
---
## 传播语法
Spread语法允许在可能需要零个或多个参数用于函数调用或元素用于数组文字的位置扩展可迭代的数组表达式或字符串或者在预期为零的位置展开对象表达式。
### 句法
对于函数调用:
```
myFunction(...iterableObj);
```
对于数组文字或字符串:
```
[...iterableObj, '4', 'five', 6];
```
### 例子
#### 传播函数调用
#### 替换申请
在要使用数组元素作为函数参数的情况下,通常使用`Function.prototype.apply` 。
```
function myFunction(x, y, z) { }
var args = [0, 1, 2];
myFunction.apply(null, args);
```
使用扩展语法,上面可以写成:
```
function myFunction(x, y, z) { }
var args = [0, 1, 2];
myFunction(...args);
```
参数列表中的任何参数都可以使用扩展语法,并且可以多次使用。
```
function myFunction(v, w, x, y, z) { }
var args = [0, 1];
myFunction(-1, ...args, 2, ...[3]);
```
### 申请新的
当使用`new`调用构造函数时,不可能**直接**使用数组并`apply` `apply`执行`[[Call]]`而不是`[[Construct]]` )。但是,由于扩展语法,可以很容易地使用数组:
```
var dateFields = [1970, 0, 1]; // 1 Jan 1970
var d = new Date(...dateFields);
```
要使用带有参数数组的new而不使用扩展语法您必须通过部分应用程序**间接**执行此操作:
```
function applyAndNew(constructor, args) {
function partial () {
return constructor.apply(this, args);
};
if (typeof constructor.prototype === "object") {
partial.prototype = Object.create(constructor.prototype);
}
return partial;
}
function myConstructor () {
console.log("arguments.length: " + arguments.length);
console.log(arguments);
this.prop1="val1";
this.prop2="val2";
};
var myArguments = ["hi", "how", "are", "you", "mr", null];
var myConstructorWithArguments = applyAndNew(myConstructor, myArguments);
console.log(new myConstructorWithArguments);
// (internal log of myConstructor): arguments.length: 6
// (internal log of myConstructor): ["hi", "how", "are", "you", "mr", null]
// (log of "new myConstructorWithArguments"): {prop1: "val1", prop2: "val2"}
```
### 传播数组文字
#### 一个更强大的数组文字
如果没有扩展语法要使用现有数组作为其中一部分创建新数组则数组文字语法不再足够必须使用pushspliceconcat等组合使用命令式代码。使用扩展语法变得更加简洁
```
var parts = ['shoulders', 'knees'];
var lyrics = ['head', ...parts, 'and', 'toes'];
// ["head", "shoulders", "knees", "and", "toes"]
```
就像扩展参数列表一样, `...`可以在数组文字中的任何地方使用,并且可以多次使用。
### 复制一个数组
```
var arr = [1, 2, 3];
var arr2 = [...arr]; // like arr.slice()
arr2.push(4);
// arr2 becomes [1, 2, 3, 4]
// arr remains unaffected
```
> **注意** 在复制数组时Spread语法有效地深入一级。因此它可能不适合复制多维数组如下例所示与Object.assign和spread语法相同
```
var a = [[1], [2], [3]];
var b = [...a];
b.shift().shift(); // 1
// Now array a is affected as well: [[], [2], [3]]
```
### 连接数组的更好方法
`Array.concat`通常用于将数组连接到现有数组的末尾。没有扩展语法,这可以完成:
```
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
// Append all items from arr2 onto arr1
arr1 = arr1.concat(arr2);
```
使用扩展语法,这将成为:
```
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1 = [...arr1, ...arr2];
```
`Array.unshift`通常用于在现有数组的开头插入值数组。没有扩展语法,这可以完成:
```
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
// Prepend all items from arr2 onto arr1
Array.prototype.unshift.apply(arr1, arr2) // arr1 is now [3, 4, 5, 0, 1, 2]
```
使用扩展语法,这将成为:
```
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1 = [...arr2, ...arr1]; // arr1 is now [3, 4, 5, 0, 1, 2]
```