最近在做项目的时候遇到了JS对象地址指向的问题,需求是某个页面是通过一个对象构建出来的,但是在关闭这个窗口的时候会清空这个对象的值,导致之前赋值的新对象值也被清空了。这个时候就要用到拷贝了。
后来就得知了JSON.parse(JSON.stringify(obj或者array))这个方法可以实现深拷贝,又过了几天发现了另一个问题,我需要将两个反序列化出来的JSON对象取一个并集,然后我就百度得知了 jQuery的 $.extend 方法。后来学习了一下发现也具有拷贝的功能。下面就先理解一下$.extend这个方法。
$.extend函数理解
- 方法的原型
jQuery.extend( target [, ] [, objectN ] ) 返回Object
描述: 将两个或更多对象的内容合并到第一个对象。
target | object1 | objectN |
---|---|---|
一个对象,如果附加的对象被传递给这个方法将那么它将接收新的属性,如果它是唯一的参数将扩展jQuery的命名空间。如果想把结果赋给一个新的对象,并且不修改参数对象,将第一个参数设为'{}',并用一个新的对象接收返回值 | 一个对象,它包含额外的属性合并到第一个参数 | 包含额外的属性合并到第一个参数 |
- 扩展方法
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}
网友评论