Note: The deep and shallow copies mentioned here are all described on the reference data type.
assignment
Copy the memory address directly (the new object changes, and the original object also changes)
The following newObj directly copies the memory address of obj, and they point to the same object, so modifying any attribute will affect each other.
const obj = {
name: '小明',
hobbies:['唱','跳','rap']
};
const newObj = obj
newObj.name = '张三'
newObj.hobbies[0] = '打篮球'
console.log(JSON.stringify(obj));
// {"name":"张三","hobbies":["打篮球","跳","rap"]}
console.log(JSON.stringify(newObj));
// {"name":"张三","hobbies":["打篮球","跳","rap"]}
shallow copy
The basic data type is to directly copy the value, and the reference data type is to copy the memory address
The following newObj, for the name attribute, directly copies the value; for the hobbies attribute, it copies the memory address.
ES6 spread operator implementation
const obj = {
name: '小明',
hobbies:['唱','跳','rap']
};
// 浅拷贝obj对象
const newObj = {...obj}
newObj.name = '张三'
newObj.hobbies[0] = '打篮球'
console.log(JSON.stringify(obj));
// {"name":"小明","hobbies":["打篮球","跳","rap"]}
console.log(JSON.stringify(newObj));
// {"name":"张三","hobbies":["打篮球","跳","rap"]}
Object.assign implementation
const obj = {
name: '小明',
hobbies: ['唱', '跳', 'rap']
};
// 浅拷贝obj对象
const newObj = Object.assign({},obj)
newObj.name = '张三'
newObj.hobbies[0] = '打篮球'
console.log(JSON.stringify(obj));
// {"name":"小明","hobbies":["打篮球","跳","rap"]}
console.log(JSON.stringify(newObj));
// {"name":"张三","hobbies":["打篮球","跳","rap"]}
ShallowCopy function implementation
const obj = {
name: '小明',
hobbies: ['唱', '跳', 'rap']
};
const newObj = shallowCopy(obj)
newObj.name = '张三'
newObj.hobbies[0] = '打篮球'
console.log(JSON.stringify(obj));
// {"name":"小明","hobbies":["打篮球","跳","rap"]}
console.log(JSON.stringify(newObj));
// {"name":"张三","hobbies":["打篮球","跳","rap"]}
// 浅拷贝函数
function shallowCopy(obj){
const newObj = {}
for(let key in obj){
newObj[key] = obj[key]
}
return newObj
}
deep copy
Open up a new space directly in the heap memory (the new object changes, the original object remains unchanged)
JSON.parse and JSON.stringify implementation
The following newObj points to a new object that is exactly the same as obj. Whether it is modifying the basic type data in newObj or the reference type data, obj will not change.
const obj = {
name: '小明',
hobbies:['唱','跳','rap']
};
// 深拷贝obj对象
const newObj = JSON.parse(JSON.stringify(obj))
newObj.name = '张三'
newObj.hobbies[0] = '打篮球'
console.log(JSON.stringify(obj));
// {"name":"小明","hobbies":["唱","跳","rap"]}
console.log(JSON.stringify(newObj));
// {"name":"张三","hobbies":["打篮球","跳","rap"]}
However, the JSON.stringify method has a disadvantage: if the data contains functions or undefined, their key-value pairs will be lost after serialization.
const obj = {
name: '小明',
hobbies: ['唱', '跳', 'rap'],
fn() {
console.log(123);
},
age: undefined
};
const newObj = JSON.parse(JSON.stringify(obj))
console.log(newObj);
// 输出的结果没有fn和age属性
implementation of deepCopy function
const obj = {
name: '小明',
hobbies: ['唱', '跳', 'rap']
};
const newObj = deepCopy(obj)
newObj.name = '张三'
newObj.hobbies[0] = '打篮球'
console.log(JSON.stringify(obj));
// {"name":"小明","hobbies":["唱","跳","rap"]}
console.log(JSON.stringify(newObj));
// {"name":"张三","hobbies":["打篮球","跳","rap"]}
// 深拷贝函数
function deepCopy(obj) {
if (typeof (obj) !== 'object' || typeof (obj) == null) return obj
const newObj = Array.isArray(obj) ? [] : {}
for (let key in obj) {
// 递归调用
newObj[key] = deepCopy(obj[key])
}
return newObj
}