原生JS 实现复杂对象深拷贝(对象值包含函数)

15次阅读

共计 956 个字符,预计需要花费 3 分钟才能阅读完成。

以前对深拷贝和浅拷贝没有太深的印象,后来才知道是因为没掉进去过它的坑里。最近掉坑了才意识到它们的重要性。
闲话少叙,来说说坑:如果我需要保存一个复杂的对象 obj 并把它赋值给 originalObj,后来对 obj 对象的某个属性值进行了修改,然后,,,我保存的初始值 originalObj 也被修改了!!!这个时候明眼人应该看出问题来了:因为我给 originalObj 赋值的时候用的是浅拷贝,所以修改 obj 的属性值的时候,originalObj 也跟着变了。这就是浅拷贝的直接表现。那么 假如我想保存一份初始值 originalObj,不管 obj 怎么修改,都保持 originalObj 始终不变,该怎么办呢?答案就是用深拷贝。。。网上有很多方法,比如 Object.assign()、JSON 对象的 parse 和 stringify、JQ 的 extend 等,但是它们有一个共同的问题就是对简单对象可以实现深拷贝,但是对复杂对象就不行了,比如这样一个对象(属性值有函数、数组、复杂对象等):

这个时候刚才那几个方法就不行了。那该怎么办呢?这个时候就需要自己写一个函数了:
function copyFn(obj) {
if (obj == null) {return null}
var result = Array.isArray(obj) ? [] : {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
if (typeof obj[key] === ‘object’) {
result[key] = copyFn(obj[key]); // 如果是对象,再次调用该方法自身
} else {
result[key] = obj[key];
}
}
}
return result;
}
然后 copy 对象的效果如下:
let obj_2 = deepCopy(obj_1);
console.log(obj_1); // 修改 name 属性之前,打印出来 name 也是 Edited
obj_1.name = ‘Edited’;
console.log(obj_1); // 修改 name 属性之后,打印出来 name 是 Edited
console.log(obj_2); // 由于是深拷贝,修改 obj_1 的 name 属性之前,不影响 obj_2 的 name 属性

希望这个用函数实现复杂对象的深拷贝的方法对您有所帮助!

正文完
 0