js的浅克隆和深度克隆

作者: 蚊子爸爸 | 来源:发表于2015-09-24 20:53 被阅读8717次

    听到这个名字的时候都被吓尿了。克隆听起来就很屌的样子。不过其实琢磨了一下根本没有什么好尿的——我特别讨厌一些人故作高深的摆出一副科学家的鸟样。

    知乎上有一句话是这样的:

    什么叫做理解了某一个概念?就是你可以用简单的语言把这个概念对你六岁的小侄女讲明白。

    深度克隆就是:把一个对象里面的东西一模一样地复制到另一个对象,并且这两个对象分别放在内存的不同地方。

    想象一个场景:我们希望给每一个注册用户建立一个数据模型,在此之前,我们要把这个用户的数据模型模板给创建出来:

    用户模板

    以后每个注册用户都会根据这个模板来生成对象。可以说这个userTemplate就是父对象了。

    现在来了一个新用户来注册,这个用户就是我非常喜欢的人民艺术家郭德纲。哈哈。我用这个模板对象复制一个新对象来,就像刚才说的,我写一个函数,把userTemplate对象的每一个属性都复制到这个新对象里,代码是这样的:

    给标签属性增加一个标签,光头

    然后我们又来了一位用户,是位美女,于是我们用刚才写的函数新复制一个对象:

    给苍井空加一个辣妹的标签

    下面我在把模型插入数据库之前,我要打印出来三个对象看看内容是不是正确,打印的结果是这样的:

    三个对象的数组属性是有问题的。

    结果傻逼了,数组属性出现了问题,3个对象的数组属性都一样。

    这很好理解,因为简单的复制对象,如果对象其中一个属性是引用型变量,就会出现这种情况,因为引用型变量保存的是内存地址,所以其实后来操作的都是同一块内存,导致了数组内容都一样。

    对,刚才上面的那一套就是浅克隆,深克隆是什么?深克隆就是在克隆的时候判断一下属性的类型是不是引用型变量,如果是的话就用递归方法让它一层一层进去复制自己。

    递归的深度克隆代码我贴到这里,因为没什么技术含量,所以没必要记录思路,只要代码就可以了。

    递归深度克隆代码

    然后用这个新写的函数去复制对象,重新让郭德纲和苍井空两位老师注册一下。

    用深度克隆的方法来克隆对象。

    这样的话再打印出来看看:

    一切正常了。

    这就是深度克隆了,其实是JS的继承的方法的一种。

    九点了,准备看会儿别的代码收工回家了。

    相关文章

      网友评论

      • Micity:如果把数组换成对象呢?
      • A貔貅:这里深度克隆不能用typeof 来判断引用类型,因为用typeof来判断数组返回的也是object ,这样就会导致,你明明传进入想要克隆的对象里的属性是数组,结果克隆要变成了对象了
        蚊子爸爸:@A貔貅 是的,那时候我还年轻 :)
      • 完美哥:用深度克隆传入那个对象的时候。 声明user1.name的时候报错undefind
        完美哥:@蚊子爸爸 还是挺厉害。 感触很深
        蚊子爸爸:@完美哥 其实细节我也记不得了,主要是表达一下到底什么是深克隆和浅克隆,实话说在我刚学JS的时候,被这两个名词吓到了,哈哈
      • exialym:咦,这样的话函数是不是木有深克隆?
        蚊子爸爸:@exialym 函数其实也可以有深克隆,其实这个文章是想表达,深克隆的意思无非是新创建一个对象,并且拥有另外一个对象的所有属性。在angular1里面,其实$injector就是一个类似具有深克隆的function对象。
      • 猩崽大叔:深入浅出,赞!
        蚊子爸爸:@对眼猩 谢谢,我还是个小菜鸟,多多交流一起提高~
      • ee6c75107d3f:写的很好,感谢。一直听别人说,克隆,感觉很高深的东西。之前一直不明白克隆和普通new模版,然后初始化之间的区别。
      • TOGGLELT:讲的很明白,赞👍🏻
        蚊子爸爸:@TOGGLELT 我很欣慰,哈哈

      本文标题:js的浅克隆和深度克隆

      本文链接:https://www.haomeiwen.com/subject/lyzicttx.html