JavaScript 数组的深度复制解析


Posted in Javascript onNovember 02, 2016

对于javascript而言,数组是引用类型,如果要想复制一个数组就要动脑袋想想了,因为包括concat、slice在内的函数,都是浅层复制。也就是说,对于一个二维数组来说,用concat来做复制,第二维的数组还是引用,修改了新数组同样会使旧数组发生改变。

    于是乎,想要写一个深度复制的函数,来帮助做组数的深度复制。

一般情况下,使用 “=” 可以实现赋值。但对于数组、对象、函数等这些引用类型的数据,这个符号就不好使了。

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 或 contcat 方法实现。示例:

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(array) 然后再 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

注意:如果数组值为函数,上述方法还是不行的。

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 数组的深度复制解析,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
基于JQuery制作的产品广告效果
Dec 08 Javascript
JS中setInterval、setTimeout不能传递带参数的函数的解决方案
Apr 28 Javascript
Javascript学习指南
Dec 01 Javascript
javascript实现简单的贪吃蛇游戏
Mar 31 Javascript
微信小程序教程之本地图片上传(leancloud)实例详解
Nov 16 Javascript
js 发布订阅模式的实例讲解
Sep 10 Javascript
用vuex写了一个购物车H5页面的示例代码
Dec 04 Javascript
详解Vue2 添加对scss的支持
Jan 02 Javascript
mui js控制开关状态、修改switch开关的值方法
Sep 03 Javascript
layer实现登录弹框,登录成功后关闭弹框并调用父窗口的例子
Sep 11 Javascript
浅谈layui使用模板引擎动态渲染元素要注意的问题
Sep 14 Javascript
Vue的Options用法说明
Aug 14 Javascript
AngularJS实现与Java Web服务器交互操作示例【附demo源码下载】
Nov 02 #Javascript
Centos7 中 Node.js安装简单方法
Nov 02 #Javascript
AngularJS入门教程之与服务器(Ajax)交互操作示例【附完整demo源码下载】
Nov 02 #Javascript
用AngularJS来实现监察表单按钮的禁用效果
Nov 02 #Javascript
AngularJS入门教程之Cookies读写操作示例
Nov 02 #Javascript
js导出excel文件的简洁方法(推荐)
Nov 02 #Javascript
AngularJS入门教程之多视图切换用法示例
Nov 02 #Javascript
You might like
php判断ip黑名单程序代码实例
2014/02/24 PHP
php实现水仙花数示例分享
2014/04/03 PHP
php实现paypal 授权登录
2015/05/28 PHP
ExtJs 表单提交登陆实现代码
2010/08/19 Javascript
Javascript 遍历页面text控件详解
2014/01/06 Javascript
javascript中match函数的用法小结
2014/02/08 Javascript
JS高级调试技巧:捕获和分析 JavaScript Error详解
2014/03/16 Javascript
Node.js中使用mongoskin操作mongoDB实例
2014/09/28 Javascript
NodeJS制作爬虫全过程
2014/12/22 NodeJs
JS实现为表格动态添加标题的方法
2015/03/31 Javascript
javascript实现很浪漫的气泡冒出特效
2020/09/05 Javascript
理解javascript正则表达式
2016/03/08 Javascript
JavaScript与ActionScript3两者的同性与差异性
2016/09/22 Javascript
分类解析jQuery选择器
2016/11/23 Javascript
谈谈jQuery之Deferred源码剖析
2016/12/19 Javascript
JS实现的简单轮播图运动效果示例
2016/12/22 Javascript
jQuery插件FusionWidgets实现的AngularGauge图效果示例【附demo源码】
2017/03/23 jQuery
jQuery EasyUI 折叠面板accordion的使用实例(分享)
2017/12/25 jQuery
js实现上传按钮并显示缩略图小轮子
2020/05/04 Javascript
Python random模块(获取随机数)常用方法和使用例子
2014/05/13 Python
基于Python os模块常用命令介绍
2017/11/03 Python
selenium python浏览器多窗口处理代码示例
2018/01/15 Python
Pandas 合并多个Dataframe(merge,concat)的方法
2018/06/08 Python
PyCharm 2020 激活到 2100 年的教程
2020/03/25 Python
python代码实现猜拳小游戏
2020/11/30 Python
HTML5之tabindex属性全面解析
2016/07/07 HTML / CSS
GLAMGLOW香港官网:明星出镜前的秘密武器
2017/03/16 全球购物
墨西哥购物网站:Elektra
2020/01/21 全球购物
马智宇结婚主持词
2014/04/01 职场文书
陈安之励志演讲稿
2014/08/21 职场文书
云冈石窟导游词
2015/02/04 职场文书
现实表现证明材料
2015/06/19 职场文书
安全教育主题班会总结
2015/08/14 职场文书
上手简单,功能强大的Python爬虫框架——feapder
2021/04/27 Python
在 HTML 页面中使用 React的场景分析
2022/01/18 Javascript
css实现左上角飘带效果的完整代码
2022/03/18 HTML / CSS