JS之深浅拷贝
1. 技巧性深浅拷贝
1.1 数组的浅拷贝
数组,我们可以利用数组的一些方法比如:slice
、concat
返回一个新数组的特性来实现拷贝。
let arr = ['old', 1, true, null, undefined, { old: "old" }];
let new_arr = arr.concat();
//var new_arr = arr.slice();
new_arr[0] = 'new';
arr[5].old = "new";
console.log(arr) // ["old", 1, true, null, undefined, {old: 'new'}]
console.log(new_arr) // ["new", 1, true, null, undefined, {old: 'new'}]
新数组和旧数组都发生了变化,也就是说使用 concat 或 slice 方法,克隆的并不彻底。
如果数组元素是基本类型,就会拷贝一份,互不影响,而如果是对象或者数组,就会只拷贝对象和数组的引用,这样我们无论在新旧数组进行了修改,两者都会发生变化。
这种复制引用的拷贝方法称之为浅拷贝,与之对应的就是深拷贝,深拷贝就是指完全的拷贝一个对象,即使嵌套了对象,两者也相互分离,修改一个对象的属性,也不会影响另一个。
1.2 数组的深拷贝
使用 JSON 的 parse 和 stringify 进行深拷贝。同样适用于对象。
var arr = ['old', 1, true, ['old1', 'old2'], { old: 1 }, function () { console.log("fun"); }]
var new_arr = JSON.parse(JSON.stringify(arr));
console.log(arr);
console.log(new_arr);
问题:new_arr 中 第五项数组元素为 null ,不能拷贝函数。
2. 对象/数组 拷贝
2.1 浅拷贝
function shallowCopy(object) {
if (!object || typeof object !== "object") return;
let obj = Array.isArray(object) ? [] : {};
for (let key in object) {
if (object.hasOwnProperty(key)) {
obj[key] = object[key];
}
}
return obj;
}
2.2 深拷贝
function deepCopy(object) {
if (!object || typeof object !== "object") return object;
let obj = Array.isArray(object) ? [] : {};
for (let key in object) {
if (object.hasOwnProperty(key)) {
obj[key] = deepCopy(object[key]);
}
}
return obj;
}