var map = new Map();
function deepClone(obj) {
if (map.get(obj)) return map.get(obj); // 防止环引用
var ret = {};
map.set(obj, ret);
Object.setPrototypeOf(ret, Object.getPrototypeOf(obj));
for (let key of Object.keys(obj)) {
let val = obj[key];
if (typeof val == 'object') {
ret[key] = deepClone(val);
} else {
ret[key] = val;
}
}
return ret;
}
var a = { a: 1, b: 2, c: { d: 1, e: 5, date: new Date() } };
a.c.loop = a;
var b = deepClone(a);
console.log(b);
console.log('b == a: ' + (b == a));
console.log('a.c == b.c: ' + (a.c == b.c));
console.log('b.c.loop = b: ' + (b.c.loop == b));
//不考虑不可枚举属性
function deepCopy(object){
var copy_object = {};
Object.setPrototypeOf(copy_object, Object.getPrototypeOf(object));
var descriptors = Object.getOwnPropertyDescriptors(object);
for (let key in descriptors) {
if (typeof descriptors[key].value === 'object') {
let { value, enumerable, writable, configurable } = descriptors[key];
Object.defineProperty(copy_object, key, {
value: deepCopy(value),
enumerable,
writable,
configurable,
});
} else {
Object.defineProperty(copy_object, key, descriptors[key]);
}
}
return copy_object;
}
function shallowCopy(object){
var copy_object = Object.create(Object.getPrototypeOf(object),Object.getOwnPropertyDescriptors(object));
return copy_object;
}
测试代码:
var o = new Object({
_a: 3,
b: [2],
});
Object.defineProperty(o, 'a', {
configurable: true,
get: function(){
return this._a;
//console.log(this);
},
set: function(newValue){
this._a = newValue;
//console.log(this.a);
},
});
o.a = 4
var o1 = shallowCopy(o);
var o2 = deepCopy(o);
console.log(o1);
console.log(o2);
o1.b.push(666);
console.log(o);
console.log(o2);