深拷贝
需要考虑环形依赖问题
function cloneDeep(value) {
function clone(target, map) {
if(target === null) return null;
if(typeof target === 'object') {
let cloneTarget = Array.isArray(target) ? [] : {}
if(map.get(target)) {
return map.get(target);
}
map.set(target, cloneTarget);
for(let key in target) {
// 对象类型
cloneTarget[key] = clone(target[key], map);
}
return cloneTarget;
} else {
// 基础类型
return target
}
}
return clone(value, new WeakMap())
}
let obj = {
a: 1,
b: {
c: 2
},
d: [{e: '3'}, '4']
}
obj.e = obj
console.log(cloneDeep(obj));
进阶版
function cloneDeep(value) {
function isObject(value) {
return value !== null && (typeof value === 'object')
}
function isFunction() { return typeof value === 'function' }
function cloneFunction(value) {
const clone = value.bind({});
for(key in value) {
clone[key] = value[key]
}
clone.prototype = Object.create(value.prototype)
return clone;
}
function isRegExp(value) { return value instanceof RegExp }
function cloneRegExp(value) {
if(value instanceof RegExp) {
const reg = new RegExp(value.source, value.flags);
reg.lastIndex = value.lastIndex;
return reg;
}
}
function clone(target, map) {
if(isObject(target)) {
// 正则
if(isRegExp(target)) return cloneRegExp(target);
// 函数
if(isFunction(target)) return cloneFunction(target);
let cloneTarget = Array.isArray(target) ? [] : {}
if(map.get(target)) {
return map.get(target);
}
map.set(target, cloneTarget);
for(let key in target) {
// 对象类型
cloneTarget[key] = clone(target[key], map);
}
return cloneTarget;
} else {
// 基础类型
return target
}
}
return clone(value, new WeakMap())
}
let obj = {
a: 1,
b: {
c: 2
},
d: [{e: '3'}, '4']
}
obj.e = obj
// console.log(cloneDeep(obj), cloneDeep.toString());
// const originalRegExp = /hello\d/ig;
// console.log(isRegExp(originalRegExp)); // true
// console.log(originalRegExp.source); // hello\d
// console.log(originalRegExp.flags); // ig
const source = cloneDeep.toString();
const fn = new Function(source)
console.log(fn(obj))