...
运算符,是
ES6
里一个新引入的运算法,也叫
展开/收集
运算符,我们每天都要和它打交道。
这篇文章,我就带你系统的回顾下这个运算符,介绍一些
基础
和
进阶
的用法。
Spread syntax allows an
iterable
, such as an
array expression
or
string
, to be expanded in places where 0 or more
arguments
or
elements
are expected or an
object expression
to be expanded in places where 0 or more key-value pairs (for object literals) are expected.
简而言之就是,
...
运算符可以展开一个
可迭代
对象重的所有项。
可迭代的对象一般是指可以被循环的,包括:
string
,
array
,
set
等等。
基础用法
基础用法 1:
展开
const a = [2, 3, 4]
const b = [1, ...a, 5]
b; // [1, 2, 3, 4, 5]
基础用法 2:
收集
function foo(a, b, ...c)
foo(1, 2, 3, 4, 5);
如果没有命名参数的话,
...
就会收集所有的参数:
function foo
(...args) {
console.log(args)
}
foo(1, 2, 3, 4, 5);
“A function’s
last parameter
can be prefixed with ... which will cause all remaining (user supplied) arguments to be placed within a "standard" javascript array.
Only the last parameter can be a rest parameter
.”
这个运算符一定是在最后一个参数的位置,也很好理解,就是“收集前面剩下的参数”。
Remember that the rest parameter
must be the last parameter
, or an
error
will occur.
不得不感叹,这个运算符设计的真的是妙,
可展开
,
可收集
,
收放自如
,当真好用。
基础用法 3: 把
类数组
转换为
数组
类数组和数组非常接近,都可以拥有一系列元素,也有
length
属性,最大的不同是:
const nodeList = document.getElementsByClassName("test");
const array = [...nodeList];
console.log(nodeList);
console.log(array);
使用
...
就可以实现类数组到数组的转换,转换之后,就可以使用数组的各种方法了。
function bar() {
var args = Array.prototype.slice.call(arguments);
args.push(1, 2, 3);
foo.apply(null, args)
}
function foo(...args) {
args.push(4, 5, 6
)
console.log(...args)
}
bar(0);
基础用法 4:
增加元素或属性
1: 为数组新增成员
const pokemon = ['KK', 'Peter'];
const charmander = '郑伊健';
const pokedex = [...pokemon, charmander];
console.log(pokedex);
2: 为对象新增属性
const basicSquirtle = { name: 'Squirtle', type: 'Water' };
const fullSquirtle = {
...basicSquirtle,
species: 'Tiny Turtle',
evolution: 'Wartortle'
};
console.log(fullSquirtle);
//Result: { name: 'Squirtle', type: 'Water', species: 'Tiny Turtle', evolution: 'Wartortle' }
合并数组:
const pokemon = ['Squirtle', 'Bulbasur', 'Charmander'];
const morePokemon = ['Totodile', 'Chikorita', 'Cyndaquil'];
const pokedex = [...pokemon, ...morePokemon];
console.log(pokedex);
//Result: [ 'Squirtle', 'Bulbasur', 'Charmander', 'Totodile', 'Chikorita', 'Cyndaquil' ]
// 对象数组也一样:
const pokemon = [
{ name: 'Squirtle', type: 'Water' },
{ name: 'Bulbasur', type: 'Plant' }
];
const morePokemon = [{ name: 'Charmander', type: 'Fire' }];
const pokedex = [...pokemon, ...morePokemon];
console.log(pokedex);
//Result: [ { name: 'Squirtle', type: 'Water' }, { name: 'Bulbasur', type: 'Plant' }, { name: 'Charmander', type: 'Fire' } ]
const baseSquirtle = {
name: 'Squirtle',
type: 'Water'
};
const squirtleDetails = {
species: 'Tiny Turtle Pokemon'
,
evolution: 'Wartortle'
};
const squirtle = { ...baseSquirtle, ...squirtleDetails };
console.log(squirtle);
//Result: { name: 'Squirtle', type: 'Water', species: 'Tiny Turtle Pokemon', evolution: 'Wartortle' }
1. 复制具有嵌套结构的数据/对象
const pokemon = {
name: 'Squirtle',
type: 'Water',
abilities: ['Torrent', 'Rain Dish']
};
const squirtleClone = { ...pokemon };
pokemon.name = 'Charmander';
pokemon.abilities.push('Surf');
console.log(squirtleClone);
//Result: { name: 'Squirtle', type: 'Water', abilities: [ 'Torrent', 'Rain Dish', 'Surf' ] }
当我们修改
原对象
的
name
属性时,我们的
克隆对象
的
name
属性没有受影响,这是符合我们预期的。
但是当修改
原对象
的
abilities
属性时,我们的克隆对象也被修改了。
原因也很简单,因为复制过来的
abilities
是一个引用类型,原数据改了,用到他的地方也会跟着改。
1、复制引用类型的数据
const pokemon = {
name: 'Squirtle',
type: 'Water',
abilities: ['Torrent', 'Rain Dish']
};
const squirtleClone = { ...pokemon, abilities: [...pokemon.abilities] };
pokemon.name = 'Charmander';
pokemon.abilities.push('Surf');
console.log(squirtleClone);
//Result: { name: 'Squirtle', type: 'Water', abilities: [ 'Torrent', 'Rain Dish' ] }
2、深克隆
2. 增加条件属性
const pokemon = {
name: 'Squirtle',
type: 'Water'
};
const abilities = ['Torrent', 'Rain dish'];
const fullPokemon = abilities ? { ...pokemon, abilities } : pokemon;
console.log(fullPokemon);
3
.
短路
const pokemon = {
name: 'Squirtle',
type: 'Water'
};
const abilities = ['Torrent', 'Rain dish'];
const fullPokemon = {
...pokemon,
...(abilities && { abilities })
};
console.log(fullPokemon);
如果
abilities
为
true
,就相当于是