1. 浅拷贝
当拷贝的是一个基本数据类型时,拷贝的就是数值;而当拷贝的是一个复杂数据类型的时,
拷贝的就是地址,相当于两个复杂数据类型指向同一个地址,其中一个数据发生改变都会改变。
例如:
(1)基本数据类型
var num = 100
var num2 = num
num2 = 200
console.log(num) // 100
console.log(num2) // 200
总结:当拷贝后的数值发生改变时,原数据不会随着改变,两个数据各不相干,在栈内存中排列。
(2)复杂数据类型
(2.1) 对象赋值
let obj = {
name: "curry",
age: 20,
obj2: {
name: "kobe",
age: 200
}
}
let obj2 = obj
obj.name = "james"
obj.obj2.name = "joden"
console.log(obj.name) // james
console.log(obj2.name) // james
console.log(obj.obj2.name) // joden
console.log(obj2.obj2.name) // jodon
(2.2) 浅拷贝方式之一 Object.assign()
let copyObj = Object.assign({}, obj)
obj.name = "sss"
obj.obj2.name = "ddd"
console.log(obj.name) // sss
console.log(copyObj.name) // curry
console.log(obj.obj2.name) // ddd
console.log(copyObj.obj2.name) // ddd
总结:使用Object.assign()来实现拷贝时,当obj对象只有一层的时候,是深拷贝,有两层
的时候,是浅拷贝。
2. 深拷贝,拷贝一个完全相同的对象,两个对象互不相干,修改其中一个,不会影响另外一个
2.1 实现方式之一 JSON.parse(JSON.stringify())
const obj = {
name: "skm",
age: 20,
obj2: {
name: "curry",
age: 22
}
}
const copyobj = JSON.parse(JSON.stringify(obj))
obj.name = "james"
obj.obj2.name = "kobe"
console.log(obj.name) // james
console.log(copyobj.name) // skm
console.log(obj.obj2.name) // kobe
console.log(copyobj.obj2.name) // curry
总结:该方法只能拷贝数组或对象,不能拷贝函数。因为JSON.stringify()不能接收函数
2.2 自定义深拷贝函数
function deepClone(oldObj){
if(oldObj == null){
return null
}
if(typeof oldObj !== "object"){
return oldObj
}
const newObj = Array.isArray(oldObj) ? [] : {}
for (const key in oldObj) {
console.log(key, oldObj[key]);
newObj[key] = deepClone(oldObj[key])
}
return newObj
}