- 什么是浅拷贝?
- 什么是深拷贝?
1.浅拷贝
只拷贝一层,更深层次对象级别只拷贝引用。
var arr = [2,4]; // 一层,可以被拷贝
var arr = [{foo:2}];// 深层次,无法浅拷贝
演示
// 浅拷贝
let obj = {
id:1,
name: 'Andy',
msg: { //对象中的对象,只拷贝了引用
age:1
}
}
let o = {}
for (var k in obj) {
o[k] = obj[k] //
}
console.log(o);
o.name = 'zs' //o复制过来进行修改不会影响obj的
o.msg.age = 12 //o修改了,某一方修改便会全局修改
console.log(o);
console.log(obj);
实现
1)ES5 concat实现or遍历赋值
const a = [2,8,5];
const b = a.concat();
console.log(b); // [2,8,5]
b[0] = 9;
console.log(b); // [9,8,5]
console.log(a); // [2,8,5]
2)ES6
const a = [2,8,5];
const b = [...a];
or
const [...b] = a;
console.log(b); // [2,8,5]
b[0] = 9;
console.log(b); // [9,8,5]
console.log(a); // [2,8,5]
// 对象的浅拷贝
Object.assign(拷贝目的地址,要拷贝的对象)
总结
- 第一层拷贝的内容相当于数据复制,修改互不干扰
- 第二层拷贝只拷贝了引用,修改其中一个也会引起另外一个的同步变化。
2.深拷贝
深拷贝每层都拷贝,不会有引用,把深层对象重新拷贝出来再给拷贝对象。
实现
1)利用递归实现
let obj = {
id:1,
name: 'Andy',
msg: {
age:1,
sex: [
2
]
}
}
let o = {}
// 封装函数,利用递归的方式进入每一层让每一层变为第一层来实现深拷贝
function deepCopy (newObj, oldObj) {
for (var k in oldObj) {
// 获取属性值
var item = oldObj[k]
// 判断这个值是否数组
if (item instanceof Array ) {
newObj[k] = []
deepCopy(newObj[k], item)
// 判断是否是对象
} else if (item instanceof Object) {
newObj[k] = {}
deepCopy(newObj[k], item)
// 是简单数据类型
} else {
newObj[k] = item
}
}
}
deepCopy(o, obj)
console.log(o);
console.log(obj);
o.msg.age = 13 //o和obj数据互不干扰
o.msg.sex[0] = 14 //o和obj数据互不干扰
总结
注意,封装函数的时候要把数组的判断放在对象判断的前面。
原因:数组也属于对象,而对象却不属于数组。
如果对象判断在前面,就不会去判断数组了。