… 扩展运算符(Spread Operator)究竟是浅复制还是深复制
扩展运算符实现的是浅拷贝(Shallow Copy),它只能复制对象的第一层属性。如果对象的属性值是基本数据类型(如字符串、数字、布尔值等),那么这些属性值会被直接复制。但如果对象的属性值是引用数据类型(如数组、对象等),那么复制的仅仅是这些引用类型数据的引用(内存地址),而不是数据本身。因此,如果修改了这些引用类型数据的内容,那么原始对象和拷贝对象中的对应数据都会发生变化。
使用场景
- 数组操作
- 合并数组:
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combined = [...arr1, ...arr2];
console.log(combined) // [1, 2, 3, 4, 5, 6]
- 复制数组:
const arr1 = [1, 2, 3];
const arr2 = [...arr1];
console.log(arr2) // [1, 2, 3];
- 将字符串转为数组:
const obj = "hello";
const arr = [...obj];
console.log(arr) // ['h', 'e', 'l', 'l', 'o']
- 函数参数列表:
function foo(a, b, c) {
console.log(a) // 1
console.log(b) // 2
console.log(c) // 3
}
const arr = [1, 2, 3]
foo(...arr)
- 对象操作
- 合并对象:
const obj1 = {a: 1, b: 2}
const obj2 = {c: 3, d: 4}
const combined = {...obj1, ...obj2}
console.log(combined) // {a: 1, b: 2, c: 3, d: 4}
注意:如果存在相同的键,后面的对象会覆盖前面的。
- 复制对象:
const obj1 = {a: 1, b: 2}
const obj2 = {...obj1}
console.log(obj2)
- 函数参数
- 收集剩余参数:
function logNames(fruit, ...names) {
console.log(fruit); // apple
console.log(names); // ['Alice', 'Bob', 'Charlie']
}
logNames('apple', 'Alice', 'Bob', 'Charlie');
在函数参数列表中使用扩展运算符可以将传递给函数的所有剩余参数收集到一个数组中。
4. 解构赋值
- 在解构赋值中使用:
const [first, ...rest] = [1, 2, 3, 4];
console.log(first); // 1
console.log(rest); // [2, 3, 4]