美文网首页
JS中深度拷贝引发的一系列“惨案”

JS中深度拷贝引发的一系列“惨案”

作者: 超人有点忙 | 来源:发表于2017-12-05 16:27 被阅读0次

    最近在做项目的时候遇到了JS对象地址指向的问题,需求是某个页面是通过一个对象构建出来的,但是在关闭这个窗口的时候会清空这个对象的值,导致之前赋值的新对象值也被清空了。这个时候就要用到拷贝了。
    后来就得知了JSON.parse(JSON.stringify(obj或者array))这个方法可以实现深拷贝,又过了几天发现了另一个问题,我需要将两个反序列化出来的JSON对象取一个并集,然后我就百度得知了 jQuery的 $.extend 方法。后来学习了一下发现也具有拷贝的功能。下面就先理解一下$.extend这个方法。

    $.extend函数理解

    1. 方法的原型
      jQuery.extend( target [, ] [, objectN ] ) 返回Object
      描述: 将两个或更多对象的内容合并到第一个对象。
    target object1 objectN
    一个对象,如果附加的对象被传递给这个方法将那么它将接收新的属性,如果它是唯一的参数将扩展jQuery的命名空间。如果想把结果赋给一个新的对象,并且不修改参数对象,将第一个参数设为'{}',并用一个新的对象接收返回值 一个对象,它包含额外的属性合并到第一个参数 包含额外的属性合并到第一个参数
    1. 扩展方法
      jQuery.extend( [deep ], target, object1 [, objectN ] )
    deep target object1 objectN
    boolean型不支持为false 如果为true 代表深拷贝 对象的扩展,接收新的属性 一个对象,包含额外属性合并到第一个参数上,如果第一个参数为空,自己就变成“第一个参数”,则会修改自己本身,然后被$.extend返回 包含额外的属性合并到第一个参数

    这就是基本的两个extend用法,需要注意的地方有很多,这里就有一个小插曲。。。我在一开始没有深刻理解,用了第一种方法。
    $.extend({},obj1,JSON.parse(JSON.stringify(obj2)));
    我的obj1 和 obj2 都是数组,但是返回值是对象,把我的数据结构改变了,我就想办法将对象再转换成数组,方法是:

    $.extend(obj1, JSON.parse(JSON.stringify(obj2)));
    obj1.length = getLength(obj1);
    obj1 = Array.prototype.slice.call(_obj1)
        function getLength(o) {
            var count = 0;
            for (var i in o) {
                count++;
            }
            return count;
        };
    

    网上查到Array.prototype.slice.call这个方法可以将对象直接转换成数组,但是我一开始试了一下发现不行,因为对象没有length属性,所以我就写了一个getLength方法,专门来取对象的长度,发现果然行得通。
    后来处于好奇心总觉得对这里没太搞清楚,其实是我自己改变了数据结构,就是因为第一个参数是"{}"的原因,改成"[]" 就可以了,带了“true”它不仅可以拷贝第一层级的属性,还可以一直“刨根问底”,将属性中的子类对象全部拷贝。这里引用一个API上的例子吧

    //1.合并两个对象,并修改第一个对象。
    var object1 = {
      apple: 0,
      banana: { weight: 52, price: 100 },
      cherry: 97
    };
    var object2 = {
      banana: { price: 200 },
      durian: 100
    };
    //Merge object2 into object1
    $.extend( object1, object2 );
    //结果:{"apple":0,"banana":{"price":200},"cherry":97,"durian":100}
     
    //2.采用递归方式合并两个对象,并修改第一个对象。
    var object1 = {
      apple: 0,
      banana: { weight: 52, price: 100 },
      cherry: 97
    };
    var object2 = {
      banana: { price: 200 },
      durian: 100
    };
    // Merge object2 into object1, recursively
    $.extend( true, object1, object2 );
    //结果:{"apple":0,"banana":{"weight":52,"price":200},"cherry":97,"durian":100}
    

    相关文章

      网友评论

          本文标题:JS中深度拷贝引发的一系列“惨案”

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