最近同事又碰到关于深浅拷贝以及赋值的问题,今天我也研究一下记录一下,加深一下记忆。
举一个简单的例子:
var people = {
age:10,
name:"小华",
arr:[1,2,3]
};
做一个 赋值操作:
var people2 = people;
然后做一个浅拷贝操作:
var people3 = {};
for (var i in people){
people3[i] = people[i]
};
然后最后再做一个深拷贝操作:
// function deepClone (obj) {
//
// if (Object.prototype.toString.call(obj).slice(8,-1) != 'Object' && Object.prototype.toString.call(obj).slice(8,-1) != 'Array') {
// return obj;
// }
//
// var newObj = obj.constructor === Array ? [] : {}; //开辟一块新的内存空间
//
// for (var i in obj) {
// newObj [i] = deepClone(obj [i]); //通过递归实现深层的复制
// }
//
// return newObj;
// }
function deepClone (obj) {
if (Object.prototype.toString.call(obj).slice(8,-1) != 'object' && Object.prototype.toString.call(obj).slice(8,-1) != 'Array') {
return obj;
}
var newObj = obj.constructor === Array ? [] : {}; //开辟一块新的内存空间
for (var i in obj) {
newObj [i] = deepClone(obj [i]); //通过递归实现深层的复制
}
return newObj;
}
deepClone :function(obj){
var str, newobj = obj.constructor === Array ? [] : {};
if(typeof obj !== 'object'){
return;
} else if(window.JSON){
str = JSON.stringify(obj); //系列化对象
newobj = JSON.parse(str); //还原
} else {
for(var i in obj){
newobj[i] = typeof obj[i] === 'object' ?
deepClone(obj[i]) : obj[i];
}
}
return newobj;
}
var people4 = deepClone(people);
------------------------------------------------------重点分割线---------------------------------------------
下面开始进行对原数据进行操作。(people2,3,4的值请自行console ^_^)
people.age = 1;
发现就只有people1的age发生改变,其他的都是10。改变 people 同时也会改赋值对象 people2,而改变浅拷贝得到的 people3 和深拷贝people4都没有改变。这就可以说明赋值得到的对象 people2 只是将指针改变,其引用的仍然是同一个对象,而浅拷贝得到的的 people3 和深拷贝的people4则是重新创建了新对象。
下面开始第二波操作: (people2,3,4的值请自行console ^_^)
people.arr[0] = 5
所以我们可以得出结论:
--- | 和原数据是否指向同一对象 | 第一层数据为基本数据类型 |原数据中包含子对象
赋值 | 是 | 改变会使原数据一同改变 | 改变会使原数据一同改变
浅拷贝 | 否 | 改变不会使原数据一同改变 | 改变会使原数据一同改变
深拷贝 | 否 | 改变不会使原数据一同改变 | 改变不会使原数据一同改变