jQuery的$.extend 浅拷贝与深拷贝
什么是$.extend?
$.extend
是 jQuery 中一个非常常用的方法,它可以将两个或多个对象合并到第一个对象中,而且是浅拷贝的。它的语法如下:
$.extend([deep ], target, object1 [, objectN ])
- first 参数
deep
:可选。如果设为true
,合并操作 recursively(即深拷贝)。 - second 参数
target
: 必选。目标对象,其他对象的属性将被附加到该对象上。需要合并到此对象的其他对象参数 1 、参数 2 ,……参数 N 。 - third 参数
object1
:必选。第一个被合并的对象。 - fourth 参数
objectN
:可选。第 N 个被合并的对象。
使用 $.extend 实现浅拷贝,目标对象和被合并的对象属性完全一致,如:
let target = {a:2};
const source = {a:3, b:4};
$.extend(target, source);
console.log(target); // {a:3, b:4}
但是对于含有对象或数组的属性,浅拷贝只是拷贝对象或数组的引用,没有真正生成新的对象或数组。示例代码如下:
let target = {lists: [1, 2, 3]};
const source = {lists: [4, 5, 6]};
$.extend(target, source);
console.log(target); // {lists: [4, 5, 6]}
深拷贝
深拷贝是在拷贝对象时,同时新建对象的引用,而不是仅仅拷贝一个指针,所以可以达到拷贝后对象不会互相影响的效果。jQuery 的 extend 方法默认是浅拷贝,如果需要用其实现深拷贝操作时,就要通过以下方法来实现。
方式一: 递归调用
使用递归函数,实现深拷贝,示例代码如下:
function deepCopy(obj) {
if (obj === null || typeof obj !== "object") {
return obj;
}
const copy = Array.isArray(obj) ? [] : {};
for (let key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
copy[key] = deepCopy(obj[key]);
}
}
return copy;
}
let obj = { aa: { bb: "cc" } };
let newObj = deepCopy(obj);
console.log(obj.aa.bb); // 'cc'
newObj.aa.bb = "dd";
console.log(obj.aa.bb); // 'cc'
方式二: JSON序列化和反序列化
JSON.parse() 和 JSON.stringify() 分别可以实现将对象序列化成字符串、从字符串中解析出对象,从而达到深拷贝的目的,示例代码如下:
let obj = { aa: { bb: "cc" } };
let newObj = JSON.parse(JSON.stringify(obj));
console.log(obj.aa.bb); // 'cc'
newObj.aa.bb = "dd";
console.log(obj.aa.bb); // 'cc'
需要注意的是,使用 JSON.parse() 和 JSON.stringify() 进行深拷贝,也有几个限制:
- 无法拷贝函数;
- 无法拷贝 null 和 undefined 类型的值;
- 无法拷贝正则表达式。
总结
jQuery 的 $.extend()
默认的拷贝方式是浅拷贝,只拷贝对象的引用,导致可能生成无法独立改变的拷贝数据,要实现深拷贝操作可以采用递归或者 JSON.parse+JSON.stringify 方法。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:jQuery的$.extend 浅拷贝与深拷贝 - Python技术站