JavaScript
并没有直接提供对象或者数组的复制方法。比如下面的代码,我们改变对象
b
的时候,对象
a
也会同时改变。
var a = {v1:1, v2:2};
var b = a;
b.v1 = 3;
console.log("对象a:", a);
console.log("对象b:", b);
控制台输出如下:
这是由于对象之间的赋值,只是将地址指向同一个,而不是真正意义上的拷贝。下面分别演示如何实现对象、数组的深拷贝,这样新生成的对象与原对象相互独立,不会互相影响。
一、数组的浅拷贝
浅拷贝(浅克隆)
:指的是只拷贝第一层的原始类型值,和第一层的引用类型地址。数组的
Array.prototype.slice()
和
Array.prototype.concat()
方法可以实现浅拷贝。
1,使用 slice 方法实现
var objects = [{ 'a': 1 }, { 'b': 2 }, { 'c': 3 }];
var shallows = objects.slice(0);
objects.pop(); //移除最后一个元素
objects[0].a = 11111; // 修改第一个元素值
console.log(objects);
console.log(shallows);
运行结果如下:
2,使用 concat 方法实现
var objects = [{ 'a': 1 }, { 'b': 2 }, { 'c': 3 }];
var shallows = objects.concat();
objects.pop(); //移除最后一个元素
objects[0].a = 11111; // 修改第一个元素值
console.log(objects);
console.log(shallows);
3,使用 Lodash 工具库
Lodash 是一个
JavaScript
实用工具库,使用它的
clone
方法可以实现对象、数组等的浅拷贝(浅克隆):
关于
Lodash
浅拷贝更详细的用法可以参考我写的另一篇文章:
JS - Lodash工具库的使用详解14(浅拷贝,深拷贝)
var objects = [{ 'a': 1 }, { 'b': 2 }, { 'c': 3 }];
var shallows = _.clone(objects);
objects.pop(); //移除最后一个元素
objects[0].a = 11111; // 修改第一个元素值
console.log(objects);
console.log(shallows);
二、对象、数组的深拷贝
深拷贝(深克隆)
:指拷贝所有的属性值,以及属性地址指向的值的内存空间。
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);
4,使用 Lodash 工具库
Lodash 是一个
JavaScript
实用工具库,使用它的
cloneDeep
方法可以实现对象、数组等的深拷贝(深克隆):