Web/05-JavaScript基础:ES6语法/07-剩余参数和扩展运算符.md
2021-07-29 11:08:52 +08:00

227 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: 07-剩余参数和扩展运算符
publish: true
---
<ArticleTopAd></ArticleTopAd>
## 剩余参数
**剩余参数**允许我们将不确定数量的**剩余的元素**放到一个**数组**中。
比如说,当函数的实参个数大于形参个数时,我们可以将剩余的实参放到一个数组中。
**传统写法**
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 中并不会报错。
```
打印结果:
```bash
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));
```
打印结果60
### 剩余参数和解构赋值配合使用
代码举例:
```js
const students = ['张三', '李四', '王五'];
let [s1, ...s2] = students;
console.log(s1); // '张三'
console.log(s2); // ['李四', '王五']
```
## 扩展运算符(展开语法)
扩展运算符和剩余参数是相反的。
剩余参数是将剩余的元素放到一个数组中;而扩展运算符是将数组或者对象拆分成逗号分隔的参数序列。
代码举例:
```js
const arr = [10, 20, 30];
...arr // 10, 20, 30 注意,这一行是伪代码,这里用到了扩展运算符
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)` 看看。
接下来,我们看一下扩展运算符的应用。
### 举例1数组赋值
数组赋值的代码举例:
```js
let arr2 = [...arr1]; // 将 arr1 赋值给 arr2
```
为了理解上面这行代码,我们先来分析一段代码:(将数组 arr1 赋值给 arr2
```javascript
let arr1 = ['www', 'smyhvae', 'com'];
let arr2 = arr1; // 将 arr1 赋值给 arr2其实是让 arr2 指向 arr1 的内存地址
console.log('arr1:' + arr1);
console.log('arr2:' + arr2);
console.log('---------------------');
arr2.push('你懂得'); //往 arr2 里添加一部分内容
console.log('arr1:' + arr1);
console.log('arr2:' + arr2);
```
运行结果:
![](http://img.smyhvae.com/20180304_1950.png)
上方代码中,我们往往 arr2 里添加了`你懂的`却发现arr1 里也有这个内容。原因是:`let arr2 = arr1;`其实是让 arr2 指向 arr1 的地址。也就是说,二者指向的是同一个内存地址。
如果不想让 arr1 和 arr2 指向同一个内存地址,我们可以借助**扩展运算符**来做:
```javascript
let arr1 = ['www', 'smyhvae', 'com'];
let arr2 = [...arr1]; //【重要代码】arr2 会重新开辟内存地址
console.log('arr1:' + arr1);
console.log('arr2:' + arr2);
console.log('---------------------');
arr2.push('你懂得'); //往arr2 里添加一部分内容
console.log('arr1:' + arr1);
console.log('arr2:' + arr2);
```
运行结果:
```bash
arr1:www,smyhvae,com
arr2:www,smyhvae,com
---------------------
arr1:www,smyhvae,com
arr2:www,smyhvae,com,你懂得
```
我们明白了这个例子,就可以避免开发中的很多业务逻辑上的 bug。
### 举例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]; // 利用扩展运算符,将伪数组转为真正的数组
```
**补充**
我们在《JavaScript基础/数组的常见方法》中也学过,还有一种方式,可以将伪数组(或者可遍历对象)转换为真正的数组。语法格式如下:
```js
let arr2 = Array.from(arrayLike);
```
## 我的公众号
想学习**更多技能**?不妨关注我的微信公众号:**千古壹号**。
扫一扫,你将发现另一个全新的世界,而这将是一场美丽的意外:
![](https://img.smyhvae.com/20200102.png)