本文内容:
1、三种方法实现对象的浅拷贝
2、两种方法实现对象的深拷贝
3、实现简单的深拷贝函数
数组
let arr = [1, 2, 3, [10, 20, 30]];
let newArr = Object.assign(arr);
newArr[3][0] = 100;
console.log(arr);
console.log(newArr);
// [ 1, 2, 3, [ 100, 20, 30 ] ]
// [ 1, 2, 3, [ 100, 20, 30 ] ]
对象
let obj = { a: 1, b: 2, c: { m: 10, n: 20 } }
let newObj = Object.assign(obj);
newObj.c.m = 100;
console.log(obj);
console.log(newObj);
// { a: 1, b: 2, c: { m: 100, n: 20 } }
// { a: 1, b: 2, c: { m: 100, n: 20 } }
数组
let arr = [1, 2, 3, [10, 20, 30]];
let newArr = [...arr];
newArr[3][0] = 100;
console.log(arr);
console.log(newArr);
// [ 1, 2, 3, [ 100, 20, 30 ] ]
// [ 1, 2, 3, [ 100, 20, 30 ] ]
对象
let obj = { a: 1, b: 2, c: { m: 10, n: 20 } }
let newObj = { ...obj };
newObj.c.m = 100;
console.log(obj);
console.log(newObj);
// { a: 1, b: 2, c: { m: 100, n: 20 } }
// { a: 1, b: 2, c: { m: 100, n: 20 } }
数组
let arr = [1, 2, 3, [10, 20, 30]];
let newArr = [];
arr.forEach((item) => {
newArr.push(item);
})
newArr[3][0] = 100;
console.log(arr);
console.log(newArr);
// [ 1, 2, 3, [ 100, 20, 30 ] ]
// [ 1, 2, 3, [ 100, 20, 30 ] ]
对象
let obj = { a: 1, b: 2, c: { m: 10, n: 20 } }
let newObj = {};
for(let key in obj){
newObj[key] = obj[key];
}
newObj.c.m = 100;
console.log(obj);
console.log(newObj);
// { a: 1, b: 2, c: { m: 100, n: 20 } }
// { a: 1, b: 2, c: { m: 100, n: 20 } }
const _ = require("lodash");
let arr = [1, 2, 3, [10, 20, 30]];
let newArr = _.cloneDeep(arr);
newArr[3][0] = 100;
console.log(arr);
console.log(newArr);
// [ 1, 2, 3, [ 10, 20, 30 ] ]
// [ 1, 2, 3, [ 100, 20, 30 ] ]
let arr = [1, 2, 3, [10, 20, 30]];
let newArr = JSON.parse(JSON.stringify(arr));
newArr[3][0] = 100;
console.log(arr);
console.log(newArr);
// [ 1, 2, 3, [ 10, 20, 30 ] ]
// [ 1, 2, 3, [ 100, 20, 30 ] ]
局限
会忽略 undefined
会忽略 symbol
不能序列化函数
不能解决循环引用的对象
function deepClone(obj) {
function isObject(para) {
return (typeof para === "object" || typeof para === "function") && para !== null;
}
if (!isObject(obj)) {
return obj;
}
let cloneObj = Array.isArray(obj) ? [] : {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
cloneObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key];
}
}
return cloneObj;
}
let arr = [1, 2, 3, [10, 20, 30]];
let newArr = deepClone(arr);
newArr[3][0] = 100;
console.log(arr);
console.log(newArr);
// [ 1, 2, 3, [ 10, 20, 30 ] ]
// [ 1, 2, 3, [ 100, 20, 30 ] ]
let obj = { a: 1, b: 2, c: { m: 10, n: 20 } }
let newObj = deepClone(obj);
newObj.c.m = 100;
console.log(obj);
console.log(newObj);
// { a: 1, b: 2, c: { m: 10, n: 20 } }
// { a: 1, b: 2, c: { m: 100, n: 20 } }
思路
引用数据类型
,若是简单数据类型
则直接返回传入的参数;数组
还是对象
,分别初始化对应的结构;for in
遍历对象,判断该属性是否为对象的自有属性obj.hasOwnProperty(key)
;引用数据类型
,若是引用数据类型,则需要递归
调用该函数,若不是则直接添加到初始化的结构上。