复制是复制出来一个新的对象,二者指向的是不同的对象,直接采用等号赋值的话二者指向的是同一个对象
也可以修改某个元素,看看另一个数组中的元素会不会被修改掉
const arr = ["孙悟空", "猪八戒", "沙和尚"]
const arr2 = arr // 不是复制,二者指向的是同一个对象
console.log(arr === arr2) // true
这种情况内存图如下
当调用slice
时,会产生一个新的数组对象,从而完成对数组的复制
const arr = ["孙悟空", "猪八戒", "沙和尚"]
const arr3 = arr.slice()
console.log(arr === arr3) // false
也可以使用new Array()
产生新对象
const arr = ["孙悟空", "猪八戒", "沙和尚"]
const arr4 = new Array(arr)
console.log(arr === arr4) // false
https://www.bilibili.com/video/BV1mG411h7aD?p=95
浅拷贝(shallow copy)
slice()
或者new Array(arr)
进行浅拷贝深拷贝(deep copy)
structuredClone(arr)
进行深拷贝例如定义如下数组,其在内存图中情况如图:
使用slice()
进行浅拷贝,从图中看出来只复制了第一层,并没有复制元素中的属性
在此时,通过代码进行验证,可以看出两个数组指向不一样,但是其中的对象是共享的,所以修改一个另一个也会发生改变:
深拷贝内存情况如图,不止复制了元素,也复制了元素里面的属性:
对于如下代码和结果也可以验证结果:
const arr = [{name:"孙悟空"}, {name:"猪八戒"}]
const arr2 = arr.slice() // 浅拷贝
const arr3 = structuredClone(arr) // 专门用来深拷贝的方法
console.log(arr)
console.log(arr3)
展开运算符:...
const arr = ["孙悟空", "猪八戒", "沙和尚"]
const arr3 = [...arr]
arr === arr3 // false
这种方式得到的也是浅拷贝
除此之外,还可以把参数展开
function sum(a, b, c) {
return a + b + c
}
const arr4 = [10, 20, 30]
let result1 = sum(arr4[0], arr4[1], arr4[2])
let result2 = sum(...arr4)
Object.assign(目标对象, 被复制的对象)
将被复制对象中的属性复制到目标对象里,并将目标对象返回
也可以使用展开运算符对对象进行复制
const obj = { name: "孙悟空", age: 18 }
// 方法一:复制到空对象后获取返回值
const obj2 = Object.assign({}, obj)
console.log(obj2)
// 方式二:直接复制到一个对象中,不会改变原有属性
const obj3 = { address: "花果山", age: 28 }
Object.assign(obj3, obj)
console.log(obj3)
也可以使用展开运算符
const obj3 = { address: "高老庄", ...obj, age: 48 } // 将obj中的属性在新对象中展开
const obj = {
name: "孙悟空",
friend: {
name: "猪八戒",
},
}
// 对obj进行浅复制
const obj2 = Object.assign({}, obj)
// 对obj进行深复制
const obj3 = structuredClone(obj)
// 利用JSON来完成深复制
const str = JSON.stringify(obj)
const obj4 = JSON.parse(str)