浅拷贝
Object.assign(target, source)
var obj1 = {
a: 1,
b: 2,
c: ['a','b','c']
}
var obj2 = Object.assign({}, obj1);
obj2.c[1] = 5;
console.log(obj1.c); // ["a", 5, "c"]
console.log(obj2.c); // ["a", 5, "c"]
扩展运算符(...)
const a = {msg: {name: "lihb"}};
const b = {...a};
a.msg.name = "lily";
console.log(b.msg.name); // lily
深拷贝
乞丐版的深拷贝 JSON.stringify(JSON.parse(obj))
var obj1 = {
a: 1,
b: 2,
c: 3
}
var objString = JSON.stringify(obj1);
var obj2 = JSON.parse(objString);
obj2.a = 5;
console.log(obj1.a); // 1
console.log(obj2.a); // 5
递归拷贝
null、undefinde、function、RegExp等特殊的值也全部拷贝成功
function deepClone(source) {
if (typeof source !== "object") { // 非对象类型(undefined、boolean、number、string、symbol),直接返回原值即可
return source;
}
if (source === null) { // 为null类型的时候
return source;
}
if (source instanceof Date) { // Date类型
return new Date(source);
}
if (source instanceof RegExp) { // RegExp正则类型
return new RegExp(source);
}
let result;
if (Array.isArray(source)) { // 数组
result = [];
source.forEach((item) => {
result.push(deepClone(item));
});
return result;
} else { // 为对象的时候
result = {};
const keys = [...Object.getOwnPropertyNames(source), ...Object.getOwnPropertySymbols(source)]; // 取出对象的key以及symbol类型的key
keys.forEach(key => {
let item = source[key];
result[key] = deepClone(item);
});
return result;
}
}
let a = {name: "a", msg: {name: "lihb"}, date: new Date("2020-09-17"), reg: new RegExp(/123/)};
let b = deepClone(a);
a.msg.name = "lily";
a.date = new Date("2020-08-08");
a.reg = new RegExp(/456/);
console.log(b);
// { name: 'a', msg: { name: 'lihb' }, date: 2020-09-17T00:00:00.000Z, reg: /123/ }
利用WeakMap、递归实现对象深拷贝。解决拷贝对象环引用爆栈问题
解决对象相互引问题
function checktype(obj){ //检查对象类型
return Object.prototype.toString.call(obj).slice(8,-1)
}
function depCopy(target,hash = new WeakMap()){ //hash 作为一个检查器,避免对象深拷贝中出现环引用,导致爆栈。
let type = checktype(target)
let result = null
if(type=="Object"){
result = {}
}else if(type=="Array"){
result = []
}else{
return target
}
if(hash.has(target)){ //检查是有存在相同的对象在之前拷贝过,有则返回之前拷贝后存于hash中的对象
return hash.get(target)
}
hash.set(target,result) //备份存在hash中,result目前是空对象、数组。后面会对属性进行追加,这里存的值是对象的栈
for(let i in target){
if(checktype(target[i])=="Object"||checktype(target[i])=="Array"){
result[i]= depCopy(target[i],hash)//属性值是对象,进行递归深拷贝
}else{
result[i]= target[i]//其他类型直接拷贝
}
}
return result
}
var b={gg:123,ff:a}
var a={
c:{
k:1,
k2:2
},
d:{
d1:[1,2],
d2:b,
d3:{
f1:'kkk'
}
}
}
let cop = depCopy(a)
网友评论