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

最近在做项目的时候遇到了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}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1、javaScript的变量类型 (1)基本类型:5种基本数据类型Undefined、Null、Boolean、...
    wengjq阅读 836评论 0 15
  • 在 JS 中有一些基本类型像是Number、String、Boolean,而对象就是像这样的东西{ name: '...
    tobAlier阅读 595评论 0 0
  • 最近的学习中,仔细研究了下深拷贝和浅拷贝,下面就来简单的总结下。 数据类型 首先我们了解下两种数据类型:1、基本类...
    iyimao阅读 765评论 0 0
  • 对于问题: var obj1 = {name:'小明'}; var obj2 = obj1; obj2.name ...
    蓝摇扼剑阅读 345评论 0 0
  • 今天是母亲节,让我想到了我和我的母亲 我母亲是一个非常能干的女性,聪明,勇敢,灵活,坚定,有担当,小的时候记得经常...
    张虹Grace阅读 315评论 1 2