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 相关文章推荐
Jquery模仿Baidu、Google搜索时自动补充搜索结果提示
Dec 26 Javascript
js二维数组排序的简单示例代码
Jan 24 Javascript
eclipse导入jquery包后报错的解决方法
Feb 17 Javascript
node.js正则表达式获取网页中所有链接的代码实例
Jun 03 Javascript
jquery分割字符串的方法
Jun 24 Javascript
完善的jquery处理机制
Feb 21 Javascript
Angular整合zTree的示例代码
Jan 24 Javascript
vue-auto-focus: 控制自动聚焦行为的 vue 指令方法
Aug 25 Javascript
JS 实现获取验证码 倒计时功能
Oct 29 Javascript
vue指令做滚动加载和监听等
May 26 Javascript
cordova+vue+webapp使用html5获取地理位置的方法
Jul 06 Javascript
Vue生命周期activated之返回上一页不重新请求数据操作
Jul 26 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类的使用 实例代码讲解
2009/12/28 PHP
php将HTML表格每行每列转为数组实现采集表格数据的方法
2015/04/03 PHP
推荐4个原生javascript常用的函数
2015/01/12 Javascript
JS实现无限级网页折叠菜单(类似树形菜单)效果代码
2015/09/17 Javascript
NodeJS的Promise的用法解析
2016/05/05 NodeJs
javascript事件模型介绍
2016/05/31 Javascript
微信公众平台开发教程(六)获取个性二维码的实例
2016/12/02 Javascript
PHP实现记录代码运行时间封装类实例教程
2017/05/08 Javascript
基于node.js express mvc轻量级框架实践
2017/09/14 Javascript
将Sublime Text 3 添加到右键中的简单方法
2017/12/12 Javascript
js拖动滑块和点击水波纹效果实例代码
2018/10/16 Javascript
vue读取本地的excel文件并显示在网页上方法示例
2019/05/29 Javascript
小程序实现分类页
2019/07/12 Javascript
原生js+ajax分页组件
2020/01/30 Javascript
Python基础教程之正则表达式基本语法以及re模块
2016/03/25 Python
使用NumPy和pandas对CSV文件进行写操作的实例
2018/06/14 Python
详解Django中间件的5种自定义方法
2018/07/26 Python
python如何求解两数的最大公约数
2018/09/27 Python
python安装pywin32clipboard的操作方法
2019/01/24 Python
python实现共轭梯度法
2019/07/03 Python
django项目环境搭建及在虚拟机本地创建django项目的教程
2019/08/02 Python
Python3实现监控新型冠状病毒肺炎疫情的示例代码
2020/02/13 Python
Django自定义YamlField实现过程解析
2020/11/11 Python
Django缓存Cache使用详解
2020/11/30 Python
中国制造网:Made-in-China.com
2019/10/25 全球购物
ORLY官网:美国专业美甲一线品牌
2019/12/11 全球购物
澳大利亚排名第一的露营和户外设备在线零售商:Outbax
2020/05/06 全球购物
应届大专毕业生自我鉴定
2014/04/08 职场文书
小学模范班主任事迹材料
2014/05/13 职场文书
2014年德育工作总结
2014/11/20 职场文书
幼儿园安全工作总结2015
2015/04/20 职场文书
上班迟到检讨书
2015/05/06 职场文书
思品教学工作总结
2015/08/10 职场文书
2019年警察入党转正申请书最新范文
2019/09/03 职场文书
开学季:喜迎新生,迎新标语少不了
2019/11/07 职场文书
详解Vue中$props、$attrs和$listeners的使用方法
2022/02/18 Vue.js