JavaScript数组和对象的复制


Posted in Javascript onMarch 21, 2017

一、数据类型

从狭义上来说,JS把所有的数据分成两大类型:基本类型和引用类型,其中基本类型包括Undefined、Null、Boolean、Number和String,引用类型为Object,常用的Array、Date、RegExp、Function等都属于Object类型。

基本型数据和引用型数据的区别之一就是,在复制变量时,基本型数据复制独立的一份新的拷贝,而引用型数据复制的是原变量的引用。下面是一个例子:

// 基本类型数据的复制
var a = 10;
var b = a; // b = 10
a = 20; // a = 20, b = 10
// 引用类型数据的复制
var m = [1, 2];
var n = m;
m[0] = 10;
console.log(n[0]); // 10

如果我想复制引用类型本身的值而非引用,显然不能采用上面的方式。

二、数组的浅复制

浅复制是指对象(数组)被复制时,其引用字段的值不会被复制,而是复制了对应字段的引用。如:

var src = [
 'alpha',
 ['bravo', 'chalie']
];
var dest = [];
for (var i = 0; i < src.length; i++) {
 dest[i] = src[i];
}
//此时,如果改变src中的引用字段,dest中相应的字段也会被改变
src[1].push('delta');
console.log(dest[1]); // ['bravo', 'chalie', 'delta']

浅复制一般用于一维数组,即数组中不存在引用类型的情况。常用的浅复制方法有:

concat方法

var src = ['alpha', 'bravo'],
  dest = [];
 dest = dest.concat(src);

concat方法更多地被用在数组合并中,比如:

var a = ['alpha', 'bravo'],
  b = ['chalie', 'delta'],
  combine;
 combine = a.concat(b);

特别要指出,concat用于数组合并时,是将两个(或多个)数组中的所有元素复制到新的对象,对于大型数组来说,开销比较大。更好的办法是把后一个数组的元素复制到前一个数组中:

var src = ['alpha', 'bravo'],
  dest = ['chalie', 'delta'];
 Array.prototype.push.apply(src, dest);

slice方法

slice方法可以从已有数组中返回选定的元素,返回的是一个新数组。

var src = ['alpha', 'bravo'],
 var dest = src.slice(0);

三、对象的浅复制

对象的浅复制可以用for-in遍历来实现,在es6中提供了更为方便的Object.assign()方法。

var src = {name: 'fox', age: 20},
  dest = null;
 dest = Object.assign({}, src);

也可以使用jQuery中的$.extend,underscore中的_.extend等方法来实现对象的复制。

四、深度复制

浅复制的应用场景有限,更多情况下,我们希望能够将对象复制出一个完整的副本,这就需要用到typeof或instanof操作符来对各个字段的类型进行判断。如果某字段是基本类型的,可以直接复制。如果某字段是引用类型的,还需要对该字段的所有字段进行上述判断,这就很容易让我们考虑使用递归来实现这个功能。

function deep_copy(src, dest) {
 for (var p in src) {
  if (Array.isArray(src[p]) || src[p] instanceof Object) {
   dest[p] = Array.isArray(src[p]) ? [] : {};
   arguments.callee(dest[p], src[p]);
  }else {
   dest[p] = src[p];
  }
 }
}

在上述代码中,由于数组是特殊的对象,因此可以用for-in来遍历。

另外,还可以使用json大法:

function deep_copy_in_json(src) {
  return JSON.parse(JSON.stringify(src));
 }

这样做虽然比较简便,但原对象的很多属性在操作后会丢失,比如construtor属性以及对象原型中的一些方法。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
js实现登陆遮罩效果的方法
Jul 28 Javascript
js仿黑客帝国字母掉落效果代码分享
Nov 08 Javascript
JavaScript中日期的相关操作方法总结
Oct 24 Javascript
Bootstrap每天必学之导航条(二)
Mar 01 Javascript
node.js+express+mySQL+ejs+bootstrop实现网站登录注册功能
Jan 12 Javascript
JS与jQuery实现ListBox上移,下移,左移,右移操作功能示例
May 31 jQuery
详解webpack打包时排除其中一个css、js文件或单独打包一个css、js文件(两种方法)
Oct 26 Javascript
浅析微信扫码登录原理(小结)
Oct 29 Javascript
详解mpvue中小程序自定义导航组件开发指南
Feb 11 Javascript
mock.js模拟前后台交互
Jul 25 Javascript
js中console在一行内打印字符串和对象的方法
Sep 10 Javascript
JavaScript快速调试的两个技巧
Nov 04 Javascript
Vue响应式添加、修改数组和对象的值
Mar 20 #Javascript
zTree实现节点修改的实时刷新功能
Mar 20 #Javascript
Vue指令的钩子函数使用方法
Mar 20 #Javascript
非常实用的vue导航钩子
Mar 20 #Javascript
Vue2.0实现1.0的搜索过滤器功能实例代码
Mar 20 #Javascript
如何解决vue与传统jquery插件冲突
Mar 20 #Javascript
Vue.js路由vue-router使用方法详解
Mar 20 #Javascript
You might like
php实现文件下载代码分享
2014/08/19 PHP
9个实用的PHP代码片段分享
2015/01/22 PHP
PHP+原生态ajax实现的省市联动功能详解
2017/08/15 PHP
javascript 正则表达式相关应介绍
2012/11/27 Javascript
JavaScript和CSS交互的方法汇总
2014/12/02 Javascript
Javascript数据结构与算法之列表详解
2015/03/12 Javascript
深入解析AngularJS框架中$scope的作用与生命周期
2016/03/05 Javascript
JS脚本实现动态给标签控件添加事件的方法
2016/06/02 Javascript
jQuery插件echarts设置折线图中折线线条颜色和折线点颜色的方法
2017/03/03 Javascript
妙用缓存调用链实现JS方法的重载
2018/04/30 Javascript
react脚手架如何配置less和ant按需加载的方法步骤
2018/11/28 Javascript
JS控制下拉列表左右选择实例代码
2020/05/08 Javascript
浅析 Vue 3.0 的组装式 API(一)
2020/08/31 Javascript
JS绘图Flot如何实现可选显示曲线图功能
2020/10/16 Javascript
JavaScript中遍历的十种方法总结
2020/12/15 Javascript
vue-router懒加载的3种方式汇总
2021/02/28 Vue.js
python选择排序算法的实现代码
2013/11/21 Python
Python利用Nagios增加微信报警通知的功能
2016/02/18 Python
python 生成器生成杨辉三角的方法(必看)
2017/04/10 Python
python3+PyQt5实现自定义分数滑块部件
2018/04/24 Python
Python中shapefile转换geojson的示例
2019/01/03 Python
Python实现查找二叉搜索树第k大的节点功能示例
2019/01/24 Python
Python qrcode 生成一个二维码的实例详解
2020/02/12 Python
使用css创建三角形 使用CSS3创建3d四面体原理及代码(html5实践)
2013/01/06 HTML / CSS
HTML5的一个显示电池状态的API简介
2015/06/18 HTML / CSS
名人珠宝设计师:Melinda Maria Jewelry
2019/03/06 全球购物
北京某公司的.net笔试题
2014/03/20 面试题
公务员培训心得体会
2013/12/28 职场文书
创业计划书——互联网商机
2014/01/12 职场文书
业务部主管岗位职责
2014/01/29 职场文书
小学生操行评语大全
2014/04/22 职场文书
工商局副局长个人对照检查材料
2014/09/25 职场文书
幼儿园园长个人总结
2015/03/02 职场文书
用python画城市轮播地图
2021/05/28 Python
Python包argparse模块常用方法
2021/06/04 Python
MongoDB支持的数据类型
2022/04/11 MongoDB