Web/05-JavaScript之ES6语法/07-剩余参数和扩展运算符.md
2020-08-24 23:22:58 +08:00

203 lines
5.0 KiB
JavaScript
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.

## 剩余参数
**剩余参数**允许我们将不确定数量的**剩余的元素**放到一个**数组**
比如说当函数的实参个数大于形参个数时我们可以将剩余的实参放到一个数组中
**传统写法**
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]; // 利用扩展运算符,将伪数组转为真正的数组
```