“…”运算符,是ES6里一个新的运算法,称为三点运算符,也叫展开/收集运算符
ES6官方的说明是,…运算符可以展开一个可迭代对象中的所有项。
可迭代的对象一般是指可以被循环的,包括string,array,set等。
const a = [2,3,4]
const b = [1,...a,5]
console.log(b) // 结果 [1,2,3,4,5]
function foo(a,b, ...c) {
console.log(a,b,c)
}
foo(1,2,3,4,5) // 结果 1,2[3,4,5]
// 如果没有命名参数的话,...就会收集所有的参数:
function foo(...args) {
console.log(args)
}
foo(1,2,3,4,5) // [1,2,3,4,5]
// 注意这个运算符一定是在最后一个参数的位置,因为官方对其定义为“收集前面剩下的参数”,如果不在最后一位,会报错。
类数组和数组最大的不同是:类数组不具备数组的一系列方法。
举例:
const node = document.getElementByClassName('test')
const arr = [...node]
console.log(node) // HTMLCollection
console.log(arr) // Array
使用…就可以实现类数组到数组的转换,转换之后,就可以使用数组的各种方法了
const pp = ['幻听', '素颜']
const man = '许嵩'
const ppMan = [...pp, man]
console.log(ppMan) // ['幻听','素颜','许嵩']
const basic = {name: '加菲', age: '3'}
const all = {
...basic,
species: '橘猫',
normal: '短尾'
}
console.log(all) // {name:'加菲',age:'3',species:'橘猫',normal:'短尾'}
const pokemon = {
name: 'Squirtle',
type: 'Water',
abilities: ['Torrent', 'Rain Dish']
}
const squirtleClone = { ...pokemon }
pokemon.name = 'Charmander'
pokemon.abilities.push('Surf')
console.log(squirtleClone)
// { name: 'Squirtle', type: 'Water', abilities: [ 'Torrent', 'Rain Dish', 'Surf' ] }
当我们修改原对象的name时候,我们的克隆对象的name属性没有受到影响,这是符合我们预期的。
但是当修改原对象的abilities属性时,我们的克隆对象也被改变了。
因为复制过来的abilities是一个引用类型,原数据改了,用到他的地方也会跟着改。
解决方案 :
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)
// { name: 'Squirtle', type: 'Water', abilities: [ 'Torrent', 'Rain Dish' ] }
const pokemon = {
name: 'Squirtle',
type: 'Water'
}
const abilities = ['Torrent', 'Rain dish']
const fullPokemon = {
...pokemon,
...(abilities && { abilities })
}
console.log(fullPokemon)
如果 abilities 为 true,就相当于是
const fullPokemon = {
...pokemon,
...{ abilities }
}
const pokemon = {
name: 'Squirtle',
type: 'Water'
}
const abilities = ['Torrent', 'Rain dish']
const fullPokemon = abilities ? { ...pokemon, abilities } : pokemon
console.log(fullPokemon)
有时候我们会遇到这样的情况,一个对象,大部分属性是相似的,只有小部分是不不同的,这时候我们就可以设置一个基础对象,具备基础属性,其他的对象可以通过扩展这个对象来得到。
const pokemon = {
name: 'Squirtle',
type: 'Water'
}
// 给abilities默认赋值
const { abilities = [], ...rest } = pokemon
const fullSquirtle = { ...rest, abilities }
console.log(rest) // { name: 'Squirtle', type: 'Water' }
console.log({ fullSquirtle }) // { name: 'Squirtle', type: 'Water', abilities: [] }