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 相关文章推荐
JS提交并解析后台返回的XML的代码
Nov 03 Javascript
jquery 插件之仿“卓越亚马逊”首页弹出菜单效果
Dec 25 Javascript
Javascript 通过json自动生成Dom的代码
Apr 01 Javascript
jquery遍历checkbox的注意事项说明
Feb 21 Javascript
防止jQuery ajax Load使用缓存的方法小结
Feb 22 Javascript
js操纵dom生成下拉列表框的方法
Feb 24 Javascript
JS实现的鼠标跟随代码(卡通手型点击效果)
Oct 26 Javascript
jquery获取复选框checkbox的值实现方法
May 30 Javascript
js实现鼠标拖动功能
Mar 20 Javascript
使用pkg打包Node.js应用的方法步骤
Oct 19 Javascript
JS实现的简单tab切换功能完整示例
Jun 20 Javascript
Vue项目移动端滚动穿透问题的实现
May 19 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遍历数组的几种方法
2012/03/22 PHP
php-fpm配置详解
2014/02/12 PHP
PHP数据对象映射模式实例分析
2019/03/29 PHP
Yii redis集合的基本使用教程
2020/06/14 PHP
jquery的$(document).ready()和onload的加载顺序
2010/05/26 Javascript
JQuery datepicker 使用方法
2011/05/20 Javascript
jQuery控制iFrame(实例代码)
2013/11/19 Javascript
jQuery源码分析之Callbacks详解
2015/03/13 Javascript
jQuery.cookie.js使用方法及相关参数解释
2017/03/06 Javascript
Bootstrap实现的标签页内容切换显示效果示例
2017/05/25 Javascript
EasyUI创建人员树的实例代码
2017/09/15 Javascript
JS判断数组那点事
2017/10/10 Javascript
详解Chai.js断言库API中文文档
2018/01/31 Javascript
Vue瀑布流插件的使用示例
2018/09/19 Javascript
详解TypeScript+Vue 插件 vue-class-component的使用总结
2019/02/18 Javascript
vue动态添加路由addRoutes之不能将动态路由存入缓存的解决
2019/02/19 Javascript
基于Vue插入视频的2种方法小结
2019/04/02 Javascript
解决pycharm双击但是无法打开的情况
2020/10/31 Javascript
Python利用带权重随机数解决抽奖和游戏爆装备问题
2016/06/16 Python
你真的了解Python的random模块吗?
2017/12/12 Python
selenium在执行phantomjs的API并获取执行结果的方法
2018/12/17 Python
Python发展简史 Python来历
2019/05/14 Python
python多线程共享变量的使用和效率方法
2019/07/16 Python
python安装第三方库如xlrd的方法
2020/10/31 Python
css3动画过渡实现鼠标跟随导航效果
2018/02/08 HTML / CSS
诗普兰迪官方网站:Splendid
2018/09/18 全球购物
意大利时尚精品店:Nugnes 1920
2020/02/10 全球购物
用Python匹配HTML tag的时候,<.*>和<.*?>有什么区别
2012/11/04 面试题
公司薪酬管理制度
2014/01/31 职场文书
军训自我鉴定200字
2014/02/13 职场文书
小学生暑假家长评语
2014/04/17 职场文书
机械工程及自动化专业求职信
2014/09/03 职场文书
教育见习报告范文
2014/11/03 职场文书
英文诗歌翻译方法(赏析)
2019/08/16 职场文书
《中国机长》观后感:敬畏生命,敬畏职责
2019/11/12 职场文书
python实现简单的井字棋
2021/05/26 Python