JavaScript-对象的浅拷贝和深拷贝
对象的拷贝分为浅拷贝和深拷贝。
浅拷贝
浅拷贝 : 浅拷贝只是拷贝一层,即对于num、boolean等简单数据类型的属性直接拷贝过来,而对于深层次的对象只拷贝其引用。
eg:
var obj = {
name: 'Johnson',
age: 20,
friend: ['Wang', 'Yang', 'Bob'],
son: {
name: 'Bill'
}
}
var obj0 = {};
for (var k in obj) {
obj0[k] = obj[k];
}
以上的for循环就是一个浅拷贝,此时obj0里面的friend属性和son属性均为原属性地址的引用,我将obj中的son属性更改,此时obj0的属性也会发生相应改变。而对于name这种简单数据类型属性发生改变,则不会影响另一个对象。
eg续:
console.log(obj);
// 在这里 obj0 的 name 属性改变为了 Sam ,而 obj 的 name 仍为 Johnson
// 但是二者的 son 对象里面的 name 却都变为了 Geo 说明其中的复杂数据类型只是拷贝了它的引用(地址)
obj0.son.name = 'Geo';
obj0.name = 'Sam';
console.log(obj0);
// 二者无论改变哪一个son对象都将使另外一个son对象发生改变
obj.son.name = 'Liya';
es6中新增了一种Object方法assign(),可代替上面的for循环,实现浅拷贝
Object.assign(obj0, obj);
深拷贝
深拷贝 : 相对于浅拷贝,深拷贝会拷贝多层,对每一个级别的数据都会拷贝。
一般可以利用递归函数实现深拷贝。
eg:
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;
}
}
}
对数组进行数据类型判断的时候可以使用 instanceof 关键字,instanceof 可以对实例对象的构造函数进行判断,object instanceof constructor 如果结果为true则constructor是object的构造函数