浅拷贝
浅拷贝(shallow copy)对对象的浅层进行复制(只复制一层)。
- Object.assign()方法 用于浅拷贝对象。
- 也可以用扩展运算符
...完成浅拷贝。
浅拷贝原理
- 利用for/in循环拿到属性名完成赋值。
- 以下代码可以看出person1和person2中的first对象指向的是同一个内存地址,所以其中的name属性改变后,另一个也会改变。
var person1 = {
name: '张三',
age: 18,
sex: 'male',
children: {
first: {
name: '张三',
age: 18
},
second: {
name: '李四',
age: 19
},
third: {
name: '王五',
age: 20
}
}
}
function clone(origin, target){
var tar = target || {};
for(var key in origin){
tar[key] = origin[key];
}
return tar;
}
var person2 = clone(person1);
person2.age = 20;
person2.children.first.name = '玛琪玛';
console.log(person1.age); // 18
console.log(person2.age); // 20
console.log(person1.children.first.name); // '玛琪玛'
console.log(person2.children.first.name); // '玛琪玛'
深拷贝
深拷贝(deep copy)不仅复制对象本身,还复制对象中的属性。
structoredClone(obj)方法 用于深拷贝对象。
深拷贝原理
- 利用
递归的方式进行循环,直到object类型全部复制完毕。 - 目标和源引用值都是独立的,不会出现同时更改的问题。
function deepClone(origin, target){
var target = target || {},
toStr = Object.prototype.toString,
arrType = '[object Array]';
for(var key in origin){
if(origin.hasOwnProperty(key)){
// 判断是否是obejct类型
// null存在历史遗留问题,也是object类型,所以需要判断。
if(typeof(origin[key]) === 'object' && origin[key] !== null){
if(toStr.call(origin[key]) === arrType){
target[key] = [];
}
else{
target[key] = {};
}
deepClone(origin[key], target[key]);
}
else{
target[key] = origin[key];
}
}
}
return target;
}