对象是引用存储,存储在堆中。当设置两个对象相等时,改变其中一个对象的属性值,另一个对象也会发生改变,这是因为共用着一个相同的对象。
var obj = {
a : 1,
b : { o : 5 },
c : function(){ },
d : [1,2,3]
}
浅复制:
var clone_obj = {}
for(var attr in obj){
clone_obj[attr] = obj[attr];
}
浅复制在for in 循环中因为不知道对象内部是否有对象,只可以遍历复制最外面的一层,这样就有可能导致引用相同的对象地址。当原对象中为value的对象值改变时,复制出的对象也会产生相应的变化,不能够做到完全分离。
深复制 法1:
可以使用简单粗暴的JSON字符串转换方式,转成字符串后再转回成对象赋值,完成深复制。不足:不能复制函数!当对象的value值中存在函数时需要注意。
var clone_obj_str = JSON.stringify(obj);
var clone_obj = JSON.parse(clone_obj_str);
深复制 法2:
通过递归来进行深复制。代码判断时条件1:区分对象和null。因为 typeof {} === typeof null ; 都为object,需要进行分离。
判断条件2:区分出数组。数组也是对象,可通过 arr.constructor === Array 和 Array.isArray(arr)(ES6)方法来进行区分。
function cloneObj(obj , clone_obj){
var clone_obj = clone_obj || {};
for(var attr in obj){
// 判断 vaule 类型
if(typeof obj[attr] === "object" && obj !== null){
// 判断 value 是数组还是对象,并赋予相应空值
clone_obj[attr] = obj[attr].constructor === Array ? [] : {};
cloneObj(obj[attr] , clone_obj[attr]);
}else{
clone_obj[attr] = obj[attr];
}
}
return clone_obj;
}