稍微有点js对象拷贝经验的朋友都知道,直接将对象A赋值给对象B,然后修改对象B中的某个值,对象A中对应的那个值也会发生变化,这让我们的开发有点头疼,其实问题点在于js的深浅拷贝,如下:
var obj1 = {
name: '张三'
}
var obj2 = obj1;
obj2.name = '李四';
console.log(obj1.name); // '李四'
ok,碰到这个问题,如何解决,直接给出答案:
var obj1 = {
name: '张三'
}
var obj2 = Object.assign({}, obj1);
obj2.name = '李四';
console.log(obj1.name); // '张三'
至此,浅拷贝成功,但存在兼容性问题,比如低端的安卓机等,这个需要注意。但细心的朋友肯定会再做一个测试,如下:
var obj1 = {
name: '张三',
friends: {
name: '刘备',
age: 33
}
}
var obj2 = Object.assign({}, obj1);
obj2.name = '李四';
obj2.friends.name = '关羽';
console.log(obj1.name); // '张三'
console.log(obj1.friends.name); // '关羽'
是的,到这一步,我们失败了,对象中嵌套对象时,Object.assign()只能拷贝一层,那如何解决呢?其实就要用到深拷贝的方法了:
var obj1 = {
name: '张三',
friends: {
name: '刘备',
age: 33
}
}
var obj2 = JSON.parse(JSON.stringify(obj1));
obj2.name = '李四';
obj2.friends.name = '关羽';
console.log(obj1.name); // '张三'
console.log(obj1.friends.name); // '刘备'
ok,深拷贝我们搞定了,再也不会修改到obj1的内容啦!但必须说明,此方法只适用于纯JSON对象的深拷贝。至于JS对象中包含了函数或其他非基本数据类型时会出现什么情况,可参考这篇文章
。解决方法是自己写一个函数调用,直接粘贴给大家:
function deepClone(obj) {
if (obj === null) return null
if (typeof obj !== 'object') return obj;
if (obj.constructor === Date) return new Date(obj);
if (obj.constructor === RegExp) return new RegExp(obj);
var newObj = new obj.constructor(); //保持继承链
for (var key in obj) {
if (obj.hasOwnProperty(key)) { //不遍历其原型链上的属性
var val = obj[key];
newObj[key] = typeof val === 'object' ? arguments.callee(val) : val; // 使用arguments.callee解除与函数名的耦合
}
}
return newObj;
}