资讯专栏INFORMATION COLUMN

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

MkkHou / 1093人阅读

摘要:网上有很多方法,比如对象的和的等,但是它们有一个共同的问题就是对简单对象可以实现深拷贝,但是对复杂对象就不行了,比如这样一个对象属性值有函数数组复杂对象等这个时候刚才那几个方法就不行了。

以前对深拷贝和浅拷贝没有太深的印象,后来才知道是因为没掉进去过它的坑里。最近掉坑了才意识到它们的重要性。

闲话少叙,来说说坑:如果我需要保存一个复杂的对象 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 属性

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/102080.html

相关文章

  • js基础入浅出

    摘要:当多个事件触发的时候,会把异步事件依次的放入里等同步事件执行完之后,再去队列里一个个执行拾遗常用方法总结面试的信心来源于过硬的基础参考高级程序设计你所不知道的深入浅出知识点思维导图经典实例总结那些剪不断理还乱的关系 持续不断更新。。。 基本类型和引用类型 vue props | Primitive vs Reference Types 基本类型和字面值之间的区别 基本类型和字面值相等,...

    phodal 评论0 收藏0
  • React 的性能优化(一)当 PureComponent 遇上 ImmutableJS

    摘要:四是在年出的持久性数据结构的库,持久性指的是数据一旦创建,就不能再被更改,任何修改或添加删除操作都会返回一个新的对象。避免大量使用操作,这样会浪费性能。尽量将设计成扁平状的。 一、痛点 在我们的印象中,React 好像就意味着组件化、高性能,我们永远只需要关心数据整体,两次数据之间的 UI 如何变化,则完全交给 React Virtual Dom 的 Diff 算法 去做。以至于我们很...

    plus2047 评论0 收藏0
  • Zepto核心模块之工具方法拾遗

    摘要:举例需要注意的是,此时回调函数中的指向的就是数组或者对象的某一项。中提供的拷贝方法,默认为浅拷贝,如果第一个参数为布尔值则表示深拷贝。 前言 平时开发过程中经常会用类似each、map、forEach之类的方法,Zepto本身也把这些方法挂载到$函数身上,作为静态方法存在,既可以给Zepto的实例使用,也能给普通的js对象使用。今天我们主要针对其提供的这些api做一些源码实现分析。 源...

    Alex 评论0 收藏0
  • Zepto核心模块之工具方法拾遗

    摘要:举例需要注意的是,此时回调函数中的指向的就是数组或者对象的某一项。中提供的拷贝方法,默认为浅拷贝,如果第一个参数为布尔值则表示深拷贝。 前言 平时开发过程中经常会用类似each、map、forEach之类的方法,Zepto本身也把这些方法挂载到$函数身上,作为静态方法存在,既可以给Zepto的实例使用,也能给普通的js对象使用。今天我们主要针对其提供的这些api做一些源码实现分析。 源...

    lcodecorex 评论0 收藏0

发表评论

0条评论

MkkHou

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<