对象中的扩展运算符(...)用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中
let zxx = {a: 1, b: 2};
let zxxs = {...zxx};
console.log(zxxs) // {a: 1, b: 2}
等价于
let zxx = {a: 1, b: 2};
let zxxs = Object.assign({}, zxx)
console.log(zxxs) // {a: 1, b: 2}
同样,如果用户自定义的属性,放在扩展运算符后面,则扩展运算符内部的同名属性会被覆盖掉。
let zxx = {a: 1, b: 2};
let zxxs = {...zxx, a:3, ...{b:3, c:2}};
console.log(zxxs) // {a: 3, b: 3, c: 2}
扩展运算符对对象实例的拷贝属于一种浅拷贝(拷贝的时候拷贝的是对象的引用)。
let zxx = {a: 1, b: 2, c: {age: 18}};
let zxxs = {...zxx};
console.log(zxxs) // {a: 3, b: 3, c: {age: 18}}
==================
zxx.c.age = 8
console.log(zxx) // {a: 3, b: 3, c: {age: 8}}
console.log(zxxs) // {a: 3, b: 3, c: {age: 8}}
function add(x, y) {
return x + y;
}
const numbers = [4, 38];
add(...numbers) // 42
const arr1 = [1, 2];
const arr2 = [...arr1];
console.log(arr2) // [1, 2]
const [first, ...rest] = [1, 2, 3, 4, 5];
console.log(first) // 1
console.log(rest) // [2, 3, 4, 5]
============
// 错误的写法
const [...rest, first] = [1, 2, 3, 4, 5];
console.log(first) // Rest element must be last element
console.log(rest)
[...'zxx'] // ["z", "x", "x"]
function foo() {
console.log(arguments) // [1, 2, 3, callee: function, Symbol(Symbol.iterator): function]
const args = [...arguments];
console.log(args) // [1, 2, 3]
}
foo(1, 2, 3)
输出如下,可以看出arguments不是一个数组,而是一个伪数组,使用扩展运算符可以将其转换成真数组
但是扩展运算符不能把没有迭代器iterator的伪数组转为数组
let likeArr = { "0":1,"1":2,"length":2 }
let arr = [...likeArr] // 报错 TypeError: object is not iterable
// 但是可以用Array.from把伪数组转为数组
let likeArr = { "0":1,"1":2,"length":2 }
let arr = Array.from(likeArr)
console.log(arr) // [1,2]
等价于apply的方式:如果想将数组元素迭代为函数参数,一般使用Function.prototype.apply 的方式进行调用。
function myFunction(x, y, z) { }
var args = [0, 1, 2];
myFunction.apply(null, args);
==========
function myFunction(x, y, z) { }
var args = [0, 1, 2];
myFunction(...args);
所有参数都可以通过展开语法来传值,也不限制多次使用展开语法。
function myFunction(v, w, x, y, z) {
console.log(...arguments) // -1 0 1 2 3
}
var args = [0, 1];
myFunction(-1, ...args, 2, ...[3]);