JS中的引用数据类型(对象和数组)有深浅拷贝两种方式
浅拷贝:与原对象共用同一内存,修改会使原对象也修改。
浅拷贝主要用ES6的Object.assign()方法实现
let obj1 = {name:'张三',age:'18'}
let obj2 = Object.assign(obj1);
obj1.name = '李四';
console.log(obj1) //{name:'李四',age:'18'}
console.log(obj2) //{name:'李四',age:'18'}
深拷贝:开辟一块新内存,将原对象的所有值复制过去,修改不会改变原对象的数据。
1、JSON的parse和stringify,缺点是对象中属性值为undefined,函数和symbol的属性会省略。
let obj1 = {
name: '张三',
age: undefined,
see: function(){
console.log("看");
},
son: {
name: '张四'
}
}
let obj2 = JSON.parse(JSON.stringify(obj1));
console.log(obj2) /* {name: '张三', son: {name: '张四'}}*/
obj1.name='李四'
console.log(obj2) /* {name: '张三', son: {name: '张四'}}*/
2、用Object.assgin({},源对象)来实现,缺点是只能复制基本数据类型(即一层),如果对象属性有属性值是引用数据类型(多层)的会相当于浅拷贝。
let obj1 = {
name: '张三',
score: [1,2,3,4,5]
}
let obj2 = Object.assign({}, obj1);
obj1.name = '李四';
console.log(obj2.name) //张三
obj1.score.push(6)
console.log(obj2.score) // [1,2,3,4,5,6]
3、自定义函数递归层层遍历
function deepClone(target){
if(target === null) return target;
if(typeof target !== 'object') return target;
const cloneTarget = Array.isArray(target) ? [] : {};
for(let prop in target){
if(target.getOwnProperty(prop)){
cloneTarget[prop] = deepClone(target[prop])
}
}
return cloneTarget;
}