神奇的展开运算符(...)

神奇的展开运算符(...)

好吧,我承认有点标题党了。展开运算符(...)其实在 ES2015 就已经得到支持,截止我写这篇文章为止已经过去了4年多了,早就不算什么新的特性了。所以它可以用来做什么呢?一句话,允许我们将一个可迭代的对象展开。

虽然只是一个简单的语法糖,但可千万别小瞧他,展开运算符简化了我们在很多场景下的代码量。废话不多说,下面开始举栗子:

作为参数传递

展开运算符最常用的一个情形就是把一个数组展开作为函数参数,下面是一个简单的示例:

1
2
3
4
5
6
7
8
9
const arr = [1, 2, 3];

function addThree(num1, num2, num3) {
return num1 + num2 + num3;
}

const result = addThree(...arr);

console.log(result); // 6

看到它的强大了吧!使用展开运算符我们可以直接在把数组展开传进函数中而不需做一些额外的工作。它能做的当然远不止于此,让我们再来看下面一个栗子。

更新对象的多个属性值

什么?!展开运算符怎么和对象扯上关系了。没错,我们可以通过直接给对象的某个键赋值的方式来更新对象的属性值,如下面这样:

1
2
3
4
5
6
7
8
9
10
const person = {
name: 'lolimay',
gender: 'boy',
age: 20,
duty: '社会主义接班人'
};

person.gender = 'girl';

console.log(person.name, person.gender); // lolimay girl

看,我们只通过一句 person.gender = 'girl' 就成功把 lolimay 变性了,JavaScript 就是这么的神奇 ;) 现在问题来了,如果我想同时修改 gender 和 age 属性怎么办呢?

1
2
3
4
5
// 小明的做法
...
person.gender = 'girl';
person.gender = 21;
...

emmmm, 这样做是没有什么问题的。但是现在借助展开运算符,我们可以有个更加简洁的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
let person = {
name: 'lolimay',
gender: 'boy',
age: 20,
duty: '社会主义接班人'
};

person = {
...person,
gender: 'girl',
age: 21
}

// Print the object
Object.keys(person).forEach(key => {
console.log(key, person[key]);
});

// name lolimay
// gender girl
// age 21
// duty 社会主义接班人

上面的写法是不是好看多了。注意这里声明 person 对象用了 let 关键字,因为在后面我们要对这个 person 对象进行重新赋值。所以展开运算符在这种使用场景下更多地被来在已有的对象的基础上来生成一个新的对象,这种情况下一般不需要去修改原有的对象。

更强大的数组字面量

感谢展开运算符,现在的数组字面量语法变得前所未有的强大,让我们看看下面这些例子:

新建一个新数组

1
2
3
var parts = ['shoulders', 'knees']; 
var lyrics = ['head', ...parts, 'and', 'toes'];
// ["head", "shoulders", "knees", "and", "toes"]

连接一个新数组

1
2
3
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1 = [...arr1, ...arr2]; // arr1 is now [0, 1, 2, 3, 4, 5]