当前位置: > > > JS - 对象、数组复制的几种方法(深拷贝)

JS - 对象、数组复制的几种方法(深拷贝)

JavaScript 并没有直接提供对象或者数组的复制方法。比如下面的代码,我们改变对象 b 的时候,对象 a 也会同时改变。
var a = {v1:1, v2:2};
var b = a;
b.v1 = 3;
console.log("对象a:", a);
console.log("对象b:", b);
控制台输出如下:

这是由于对象之间的赋值,只是将地址指向同一个,而不是真正意义上的拷贝。下面分别演示如何实现对象、数组的深拷贝,这样新生成的对象与原对象相互独立,不会互相影响。

一、对象的深拷贝

对象复制(Object Clone)通常有如下几种方法:

1,通过对象序列化实现

我们可以将对象序列化再解析回来实现对象拷贝(注意:对象中的函数 function 不会被复制)
var a = {v1:1, v2:2};
var b = JSON.parse(JSON.stringify(a));
b.v1 = 3;
console.log("对象a:",a);
console.log("对象b:",b);

运行结果如下:

2,通过递归遍历实现

(1)我们定义一个 clone 方法实现深度复制功能(Deep Copy),其内部实现原理就是将对象的属性遍历一遍,赋给一个新的对象。
//自定义的复制方法
function clone(obj) {
  var copy = {};
  for (var attr in obj) {
    copy[attr] = typeof(obj[attr])==='object' ? clone(obj[attr]) : obj[attr];
  }
  return copy;
}

//测试样例
var a = {v1:1, v2:2};
var b = clone(a);
b.v1 = 3;
console.log("对象a:",a);
console.log("对象b:",b);

(2)也可以直接给 Object 增加个 clone 方法,其内部实现原来同上面是一样的。
//自定义的复制方法
Object.prototype.clone = function() {
  var copy = (this instanceof Array) ? [] : {};
  for (var attr in this) {
    if (this.hasOwnProperty(attr)){
      copy[attr] = typeof(this[attr])==='object' ? clone(this[attr]) : this[attr];
    }
  }
  return copy;
};

//测试样例
var a = {v1:1, v2:2};
var b = a.clone();
b.v1 = 3;
console.log("对象a:",a);
console.log("对象b:",b);

3,使用 jQuery 复制

jQuery 自带的 extend 方法可以用来实现对象的复制。
var a = {v1:1, v2:2};
var b = {};
$.extend(b,a);
b.v1 = 3;
console.log("对象a:",a);
console.log("对象b:",b);

二、数组的深拷贝

数组同样有如下几种方法实现复制:

1,使用 slice 方法实现

var a = [1, 2];
var b = a.slice(0);
b.push(3);
console.log("数组a:", a);
console.log("数组b:", b);
运行结果如下:

2,使用 concat 方法实现

var a = [1, 2];
var b = a.concat();
b.push(3);
console.log("数组a:", a);
console.log("数组b:", b);
评论0