浅拷贝:
function clone (source) {
let target = {};
for (let key in source) {
if (source.hasOwnProperty(key)) {
target[key] = source[key];
}
}
return target;
}
// 测试用例
var a = {
name: "muyiy",
book: {
title: "You Don't Know JS",
price: "45"
},
a1: undefined,
a2: null,
a3: 123
}
var b = clone(a);
a.name = "高级前端进阶";
a.book.price = "55";
console.log(b);
// {
// name: 'muyiy',
// book: { title: 'You Don\'t Know JS', price: '55' },
// a1: undefined,
// a2: null,
// a3: 123
// }
深拷贝:
function deepClone (source) {
if (!isObject(source)) {
return source;
}
let target = Array.isArray(source) ? [] : {};
for (let key in source) {
if (source.hasOwnProperty(key)) {
if (isObject(source[key])) {
target[key] = deepClone(source[key]);
} else {
target[key] = source[key];
}
}
}
return target;
}
注: 这种实现方法遇到循环引用会抛出错误;
解决方案很简单,其实就是循环检测,我们设置一个数组或者哈希表存储已拷贝过的对象,当检测到当前对象已存在于哈希表中时,取出该值并返回即可。
function deepClone (source, hash = new WeakMap()) {
if (!isObject(source)) return source;
if (hash.has(source)) return hash.get(source);
let target = Array.isArray(source) ? [] : {};
hash.set(source, target);
for (let key in source) {
if (source.hasOwnProperty(key)) {
if (isObject(source[key])) {
target[key] = deepClone(source[key], hash);
} else {
target[key] = source[key];
}
}
}
return target;
}
完美!!!!!!!