2021-07-29 11:08:52 +08:00
|
|
|
|
---
|
|
|
|
|
title: 07-剩余参数和扩展运算符
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
<ArticleTopAd></ArticleTopAd>
|
|
|
|
|
|
2020-08-23 23:32:42 +08:00
|
|
|
|
## 剩余参数
|
|
|
|
|
|
|
|
|
|
**剩余参数**允许我们将不确定数量的**剩余的元素**放到一个**数组**中。
|
|
|
|
|
|
|
|
|
|
比如说,当函数的实参个数大于形参个数时,我们可以将剩余的实参放到一个数组中。
|
|
|
|
|
|
|
|
|
|
**传统写法**:
|
|
|
|
|
|
|
|
|
|
ES5 中,在定义方法时,参数要确定个数,如下:(程序会报错)
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
function fn(a, b, c) {
|
|
|
|
|
console.log(a);
|
|
|
|
|
console.log(b);
|
|
|
|
|
console.log(c);
|
|
|
|
|
console.log(d);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn(1, 2, 3);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
上方代码中,因为方法的参数是三个,但使用时是用到了四个参数,所以会报错:
|
|
|
|
|
|
|
|
|
|
![](http://img.smyhvae.com/20180304_1638.png)
|
|
|
|
|
|
|
|
|
|
**ES6 写法**:
|
|
|
|
|
|
|
|
|
|
ES6 中,我们有了剩余参数,就不用担心报错的问题了。代码可以这样写:
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
const fn = (...args) => {
|
|
|
|
|
//当不确定方法的参数时,可以使用剩余参数
|
|
|
|
|
console.log(args[0]);
|
|
|
|
|
console.log(args[1]);
|
|
|
|
|
console.log(args[2]);
|
|
|
|
|
console.log(args[3]);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
fn(1, 2);
|
|
|
|
|
fn(1, 2, 3); //方法的定义中了四个参数,但调用函数时只使用了三个参数,ES6 中并不会报错。
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
打印结果:
|
|
|
|
|
|
2020-08-24 23:22:58 +08:00
|
|
|
|
```bash
|
2020-08-23 23:32:42 +08:00
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
|
undefined
|
|
|
|
|
undefined
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
|
3
|
|
|
|
|
undefined
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
上方代码中注意,args 参数之后,不能再加别的参数,否则编译报错。
|
|
|
|
|
|
|
|
|
|
下面这段代码,也是利用到了剩余参数:
|
|
|
|
|
|
|
|
|
|
```js
|
|
|
|
|
function fn1(first, ...args) {
|
|
|
|
|
console.log(first); // 10
|
|
|
|
|
console.log(args); // 数组:[20, 30]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn1(10, 20, 30);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 剩余参数的举例:参数求和
|
|
|
|
|
|
|
|
|
|
代码举例:
|
|
|
|
|
|
|
|
|
|
```js
|
|
|
|
|
const sum = (...args) => {
|
|
|
|
|
let total = 0;
|
|
|
|
|
args.forEach(item => total += item); // 注意 forEach里面的代码,写得 很精简
|
|
|
|
|
return total;
|
|
|
|
|
};
|
|
|
|
|
console.log(sum(10, 20, 30));
|
|
|
|
|
```
|
2020-08-24 23:22:58 +08:00
|
|
|
|
|
2020-08-23 23:32:42 +08:00
|
|
|
|
打印结果:60
|
|
|
|
|
|
|
|
|
|
### 剩余参数和解构赋值配合使用
|
|
|
|
|
|
|
|
|
|
代码举例:
|
|
|
|
|
|
|
|
|
|
```js
|
|
|
|
|
const students = ['张三', '李四', '王五'];
|
|
|
|
|
let [s1, ...s2] = students;
|
|
|
|
|
|
|
|
|
|
console.log(s1); // '张三'
|
|
|
|
|
console.log(s2); // ['李四', '王五']
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 扩展运算符(展开语法)
|
|
|
|
|
|
|
|
|
|
扩展运算符和剩余参数是相反的。
|
|
|
|
|
|
|
|
|
|
剩余参数是将剩余的元素放到一个数组中;而扩展运算符是将数组或者对象拆分成逗号分隔的参数序列。
|
|
|
|
|
|
|
|
|
|
代码举例:
|
|
|
|
|
|
|
|
|
|
```js
|
|
|
|
|
const arr = [10, 20, 30];
|
2020-08-24 23:22:58 +08:00
|
|
|
|
...arr // 10, 20, 30 注意,这一行是伪代码,这里用到了扩展运算符
|
2020-08-23 23:32:42 +08:00
|
|
|
|
console.log(...arr); // 10 20 30
|
|
|
|
|
|
|
|
|
|
console.log(10, 20, 30); // 10 20 30
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
上面的代码要仔细看:
|
|
|
|
|
|
|
|
|
|
`arr`是一个数组,而`...arr`则表示`10, 20, 30`这样的序列。
|
|
|
|
|
|
|
|
|
|
我们把`...arr` 打印出来,发现打印结果竟然是 `10 20 30`,为啥逗号不见了呢?因为逗号被当作了 console.log 的参数分隔符。如果你不信,可以直接打印 `console.log(10, 20, 30)` 看看。
|
|
|
|
|
|
2020-08-24 23:22:58 +08:00
|
|
|
|
接下来,我们看一下扩展运算符的应用。
|
|
|
|
|
|
|
|
|
|
### 举例1:数组赋值
|
2020-08-23 23:32:42 +08:00
|
|
|
|
|
2020-08-24 23:22:58 +08:00
|
|
|
|
数组赋值的代码举例:
|
|
|
|
|
|
|
|
|
|
```js
|
|
|
|
|
let arr2 = [...arr1]; // 将 arr1 赋值给 arr2
|
|
|
|
|
```
|
2020-08-23 23:32:42 +08:00
|
|
|
|
|
2020-08-24 23:22:58 +08:00
|
|
|
|
为了理解上面这行代码,我们先来分析一段代码:(将数组 arr1 赋值给 arr2)
|
2020-08-23 23:32:42 +08:00
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
let arr1 = ['www', 'smyhvae', 'com'];
|
|
|
|
|
let arr2 = arr1; // 将 arr1 赋值给 arr2,其实是让 arr2 指向 arr1 的内存地址
|
|
|
|
|
console.log('arr1:' + arr1);
|
|
|
|
|
console.log('arr2:' + arr2);
|
|
|
|
|
console.log('---------------------');
|
|
|
|
|
|
2020-08-24 23:22:58 +08:00
|
|
|
|
arr2.push('你懂得'); //往 arr2 里添加一部分内容
|
2020-08-23 23:32:42 +08:00
|
|
|
|
console.log('arr1:' + arr1);
|
|
|
|
|
console.log('arr2:' + arr2);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
运行结果:
|
|
|
|
|
|
|
|
|
|
![](http://img.smyhvae.com/20180304_1950.png)
|
|
|
|
|
|
|
|
|
|
上方代码中,我们往往 arr2 里添加了`你懂的`,却发现,arr1 里也有这个内容。原因是:`let arr2 = arr1;`其实是让 arr2 指向 arr1 的地址。也就是说,二者指向的是同一个内存地址。
|
|
|
|
|
|
2020-08-24 23:22:58 +08:00
|
|
|
|
如果不想让 arr1 和 arr2 指向同一个内存地址,我们可以借助**扩展运算符**来做:
|
2020-08-23 23:32:42 +08:00
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
let arr1 = ['www', 'smyhvae', 'com'];
|
2020-08-24 23:22:58 +08:00
|
|
|
|
let arr2 = [...arr1]; //【重要代码】arr2 会重新开辟内存地址
|
2020-08-23 23:32:42 +08:00
|
|
|
|
console.log('arr1:' + arr1);
|
|
|
|
|
console.log('arr2:' + arr2);
|
|
|
|
|
console.log('---------------------');
|
|
|
|
|
|
|
|
|
|
arr2.push('你懂得'); //往arr2 里添加一部分内容
|
|
|
|
|
console.log('arr1:' + arr1);
|
|
|
|
|
console.log('arr2:' + arr2);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
运行结果:
|
|
|
|
|
|
2020-08-24 23:22:58 +08:00
|
|
|
|
```bash
|
|
|
|
|
arr1:www,smyhvae,com
|
|
|
|
|
arr2:www,smyhvae,com
|
|
|
|
|
---------------------
|
|
|
|
|
arr1:www,smyhvae,com
|
|
|
|
|
arr2:www,smyhvae,com,你懂得
|
|
|
|
|
```
|
2020-08-23 23:32:42 +08:00
|
|
|
|
|
|
|
|
|
我们明白了这个例子,就可以避免开发中的很多业务逻辑上的 bug。
|
2020-08-24 23:22:58 +08:00
|
|
|
|
|
|
|
|
|
### 举例2:合并数组
|
|
|
|
|
|
|
|
|
|
代码举例:
|
|
|
|
|
|
|
|
|
|
```js
|
|
|
|
|
let arr1 = ['王一', '王二', '王三'];
|
|
|
|
|
let arr2 = ['王四', '王五', '王六'];
|
|
|
|
|
// ...arr1 // '王一','王二','王三'
|
|
|
|
|
// ...arr2 // '王四','王五','王六'
|
|
|
|
|
|
|
|
|
|
// 方法1
|
|
|
|
|
let arr3 = [...arr1, ...arr2];
|
|
|
|
|
console.log(arr3); // ["王一", "王二", "王三", "王四", "王五", "王六"]
|
|
|
|
|
|
|
|
|
|
// 方法2
|
|
|
|
|
arr1.push(...arr2);
|
|
|
|
|
console.log(arr1); // ["王一", "王二", "王三", "王四", "王五", "王六"]
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 举例3:将伪数组或者可遍历对象转换为真正的数组
|
|
|
|
|
|
|
|
|
|
代码举例:
|
|
|
|
|
|
|
|
|
|
```js
|
|
|
|
|
const myDivs = document.getElementsByClassName('div');
|
|
|
|
|
const divArr = [...myDivs]; // 利用扩展运算符,将伪数组转为真正的数组
|
|
|
|
|
```
|
2020-08-25 20:47:55 +08:00
|
|
|
|
|
|
|
|
|
**补充**:
|
|
|
|
|
|
|
|
|
|
我们在《JavaScript基础/数组的常见方法》中也学过,还有一种方式,可以将伪数组(或者可遍历对象)转换为真正的数组。语法格式如下:
|
|
|
|
|
|
|
|
|
|
```js
|
|
|
|
|
let arr2 = Array.from(arrayLike);
|
|
|
|
|
```
|
2020-08-25 21:35:30 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 我的公众号
|
|
|
|
|
|
2021-05-24 12:43:12 +08:00
|
|
|
|
想学习**更多技能**?不妨关注我的微信公众号:**千古壹号**。
|
2020-08-25 21:35:30 +08:00
|
|
|
|
|
|
|
|
|
扫一扫,你将发现另一个全新的世界,而这将是一场美丽的意外:
|
|
|
|
|
|
2021-05-24 12:48:27 +08:00
|
|
|
|
![](https://img.smyhvae.com/20200102.png)
|