deep clone
Opened this issue · 0 comments
Akiq2016 commented
function getType(data) {
let type = Object.prototype.toString.call(data).slice(8, -1).toLocaleLowerCase();
if (type === 'object') {
if (data instanceof Set) {
type = 'set';
} else if (data instanceof Map) {
type = 'map';
} else if (data instanceof Function) {
type = 'function';
}
}
return type;
}
function cloneArr(res, data, hash) {
data.forEach((item) => {
res.push(cloneDeep(item, hash));
});
return res;
}
function clonePlainObject(res, data, hash) {
for (let key in data) {
res[key] = cloneDeep(data[key], hash);
}
return res;
}
function cloneSet(res, data, hash) {
Array.from(data, (val) => {
res.add(cloneDeep(val, hash));
})
return res;
}
function cloneMap(res, data, hash) {
Array.from(data, ([key, value]) => {
res.set(cloneDeep(key, hash), cloneDeep(value, hash))
})
return res;
}
/**
* @param {any} data
*/
function cloneDeep(data, hash = new WeakMap()) {
let res;
// handle circular scene
if (hash.has(data)) {
return hash.get(data);
}
if (typeof data === 'object') {
res = new data.constructor();
hash.set(data, res);
}
switch (getType(data)) {
case 'array': res = cloneArr(res, data, hash); break;
case 'object': res = clonePlainObject(res, data, hash); break;
case 'set': res = cloneSet(res, data, hash); break;
case 'map': res = cloneMap(res, data, hash); break;
default: res = data; break;
}
return res;
}
let a = {
a: 1,
b: 2,
c: {
cc: 1,
dd: [1, 2, 3],
ee: {
gg: '213'
},
hh: {
ii: {
name: 'jjjj',
}
}
},
i: new Set([1,2,2,3, { a: 1 }]),
j: new Map([
['key', 'value'],
[['key'], 'value'],
])
};
a.h = a;
a.c.hh.kk = a.c.hh;
let b = cloneDeep(a);
console.log(a)
console.log('----')
console.log(b);
console.log(a.a === b.a === true)
console.log(a.b === b.b === true)
console.log(a.c === b.c === false)
console.log(a.c.cc === b.c.cc === true)
console.log(a.c.dd === b.c.dd === false)
console.log(a.c.ee === b.c.ee === false)
console.log(a.c.ee.gg === b.c.ee.gg === true)
console.log(a.i === b.i === false)
console.log(a.j === b.j === false)
console.log(a.h === a, b.h === b )