简单了解下深拷贝
在了解深拷贝之前,我们需要对浅拷贝有一定的理解。
什么是深浅拷贝
浅拷贝:简单来说,浅拷贝就是创建一个新的对象,这个对象有着原始对象属性值的拷贝。如果不进行深拷贝,那么一个对像的值改变了就会影响到另一个对象的值。
深拷贝:了解了浅拷贝的概念,我们就可以将深拷贝理解为在内存中开辟一个新的空间,存放新对象,并且修改新对象的值不会影响原对象。
JSON方法拷贝的缺陷
说到深拷贝,相信很多人首先就会想到 JSON 方法:
let obj = {
name: "小明",
age: 20
};
let copyObj = JSON.parse(JSON.stringify(obj));
console.log(obj);
console.log(copyObj);
但实际上,这个方法进行深拷贝是存在缺陷的。例如,对象中存在函数时既无法被拷贝下来:
let objHave = {
name: "小明",
age: 20,
doing: function () {
console.log("爱做的事情");
}
};
let copyHave = JSON.parse(JSON.stringify(objHave));
console.log(objHave);
console.log(copyHave);
很复杂但不容易出错的一种方法
这里给大家提供一个挺不错的深拷贝方法,有需要的小伙伴可以把它封装起来:
// deepClone source 原对象
const deepClone = (source, cache) => {
if (!cache) {
cache = new Map();
}
if (source instanceof Object) { // 不考虑跨 iframe
if (cache.get(source)) {
return cache.get(source)
}
let result;
if (source instanceof Function) {
if (source.prototype) { // 有 prototype 及时普通函数
result = function () {
return source.apply(this, arguments);
}
} else {
result = (...args) => {
return source.call(undefined, ...args);
}
}
} else if (source instanceof Array) {
result = []
} else if (source instanceof Date) {
result = new Date(source - 0)
} else if (source instanceof RegExp) {
result = new RegExp(source.source, source.flags)
} else {
result = {}
}
cache.set(source, result);
for (let key in source) {
if (source.hasOwnProperty(key)) {
result[key] = deepClone(source[key], cache)
}
}
return result
} else {
return source
}
}
let objDoing = deepClone(objHave);
console.log(objHave);
console.log(objDoing);
这里是万物之恋,我们下次再见了!