JavaScript 数组深度复制的多种实现方案
本文解析JavaScript中数组深度复制的多种实现方式。针对引用类型导致的浅拷贝问题,介绍了简单遍历、slice与concat变通法,以及利用JSON序列化、原型链扩展和jQuery extend插件进行深度复制的具体代码与注意事项,包括兼容性与函数处理限制。
JavaScript 数组深度复制的多种实现方案
在JavaScript中,数组属于引用类型。若需复制数组,需注意concat、slice等内置方法仅执行浅层复制。这意味着对于二维或多维数组,使用这些方法复制后,嵌套数组仍保持引用关系,修改新数组中的嵌套部分会同步影响原数组。
因此,需要编写专门的深度复制函数来解决这一问题。
通常,“=”运算符可用于基本类型赋值,但对于数组、对象和函数等引用类型,直接赋值无法实现独立副本,仅复制了引用地址。
数组的简单复制
1. 数组的简单复制
1.1 简单遍历
最基础且直观的方法是手动循环处理。示例代码如下:
JavaScript
function array_copy(arr) {
var out = [], i, len;
if (out[i] instanceof Array === false){
return arr;
}
for (i = 0, len = arr.length; i < len; i++) {
if (out[i] instanceof Array){
out[i] = deepcopy(arr[i]);
} else {
out[i] = arr[i];
}
};
return a;
}
//测试
var arr1 = [1, 2, 3, 4],
arr2 = array_copy(arr1);
console.log(arr1, arr2);
arr2[2] = 10;
console.log(arr1[2], arr2[2]);
function array_copy(arr) {
var out = [], i, len;
if (out[i] instanceof Array === false){
return arr;
}
for (i = 0, len = arr.length; i < len; i++) {
if (out[i] instanceof Array){
out[i] = deepcopy(arr[i]);
} else {
out[i] = arr[i];
}
};
return a;
}
//测试
var arr1 = [1, 2, 3, 4],
arr2 = array_copy(arr1);
console.log(arr1, arr2);
arr2[2] = 10;
console.log(arr1[2], arr2[2]);
1.2 变通的复制实现
面试中常见的技巧是利用slice或concat方法。示例如下:
JavaScript
var arr1 = [1, 2, 3, 4],
arr2 = arr1.slice(0),
arr3 = arr1.concat();
console.log(arr1, arr2, arr3);
arr2[2] = 10;
arr3[2] = 11;
console.log(arr1[2], arr2[2], arr3[2]);
var arr1 = [1, 2, 3, 4],
arr2 = arr1.slice(0),
arr3 = arr1.concat();
console.log(arr1, arr2, arr3);
arr2[2] = 10;
arr3[2] = 11;
console.log(arr1[2], arr2[2], arr3[2]);
数组的深度复制
2. 数组的深度复制
对于仅包含非引用类型值的一维数组,上述简单方法已足够。但若涉及嵌套引用类型,则需采用深度复制策略。
2.1 使用 JSON 方法
可通过JSON.stringify将数组转为字符串,再经JSON.parse转回对象。示例:
JavaScript
var arr1 = [1, 2, [3, 4], {a: 5, b: 6}, 7],
arr2 = JSON.parse(JSON.stringify(arr1));
console.log(arr1, arr2);
arr2[1] = 10;
arr2[3].a = 20;
console.log(arr1[1], arr2[1]);
console.log(arr1[3], arr2[3]);
var arr1 = [1, 2, [3, 4], {a: 5, b: 6}, 7],
arr2 = JSON.parse(JSON.stringify(arr1));
console.log(arr1, arr2);
arr2[1] = 10;
arr2[3].a = 20;
console.log(arr1[1], arr2[1]);
console.log(arr1[3], arr2[3]);
该方法在老旧浏览器中可能存在兼容性问题。如需兼容,可引入如下脚本:
https://github.com/douglascrockford/JSON-js/blob/master/json2.js
注意:若数组元素包含函数,此JSON方法无法正确复制。
2.2 深度复制的完全实现
针对多维嵌套及对象值,可通过原型扩展实现(虽不推荐直接修改原型,但此处仅为示例):
JavaScript
Object.prototype.clone = function () {
var o = {};
for (var i in this) {
o[i] = this[i];
}
return o;
};
Array.prototype.clone = function () {
var arr = [];
for (var i = 0; i < this.length; i++)
if (typeof this[i] !== 'object') {
arr.push(this[i]);
} else {
arr.push(this[i].clone());
}
return arr;
};
//测试1 Object
var obj1 = {
name: 'Rattz',
age: 20,
hello: function () {
return "I'm " + name;
}
};
var obj2 = obj1.clone();
obj2.age++;
console.log(obj1.age);
//测试2 Array
var fun = function(log) {console.log},
arr1 = [1, 2, [3, 4], {a: 5, b: 6}, fun],
arr2 = arr1.clone();
console.log(arr1, arr2);
arr2[2][1]= 'Mike';
arr2[3].a = 50;
arr2[4] = 10;
console.log(arr1, arr2);
Object.prototype.clone = function () {
var o = {};
for (var i in this) {
o[i] = this[i];
}
return o;
Array.prototype.clone = function () {
var arr = [];
for (var i = 0; i < this.length; i++)
if (typeof this[i] !== 'object') {
arr.push(this[i]);
} else {
arr.push(this[i].clone());
}
return arr;
//测试1 Object
var obj1 = {
name: 'Rattz',
age: 20,
hello: function () {
return "I'm " + name;
}
var obj2 = obj1.clone();
console.log(obj1.age);
//测试2 Array
var fun = function(log) {console.log},
arr1 = [1, 2, [3, 4], {a: 5, b: 6}, fun],
arr2 = arr1.clone();
console.log(arr1, arr2);
arr2[2][1]= 'Mike';
arr2[3].a = 50;
arr2[4] = 10;
console.log(arr1, arr2);
2.3 使用 jQuery 的 extend 方法
若项目使用jQuery,可直接调用extend插件方法。示例:
JavaScript
var arr1 = [1, 2, [3, 4], {a: 5, b: 6}, 7],
arr2 = $.extend(true, [], arr1);
console.log(arr1, arr2);
arr2[1] = 10;
console.log(arr1, arr2);
var arr1 = [1, 2, [3, 4], {a: 5, b: 6}, 7],
arr2 = $.extend(true, [], arr1);
console.log(arr1, arr2);
arr2[1] = 10;
console.log(arr1, arr2);
以上介绍了JavaScript数组深度复制的几种主要解析方法,希望有所帮助。如有疑问欢迎留言,小编会及时回复。感谢对本站的支持!
JS合并多个数组的三种方法:concat、spread与flat
2026-11-05 17:39:45
JavaScript怎么准确判断数据类型:typeof、instanceof与Object.prototype.toString
2026-11-05 17:09:21
JS中将数组和对象混合组装为JSON字符串
2026-11-05 16:41:42
JS运算符优先级与结合性的区别是什么?
2026-11-05 13:22:02
JS Map怎么只遍历Key或Value
2026-11-05 13:00:36
相关标签:
