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 相关文章推荐
javascript 解析后的xml对象的读取方法细解
Jul 25 Javascript
理解Javascript_06_理解对象的创建过程
Oct 15 Javascript
jQuery点击tr实现checkbox选中的方法
Mar 19 Javascript
举例讲解JavaScript中关于对象操作的相关知识
Nov 16 Javascript
javascript电商网站抢购倒计时效果实现
Nov 19 Javascript
ionic实现下拉刷新载入数据功能
May 11 Javascript
JS实现对json对象排序并删除id相同项功能示例
Apr 18 Javascript
再谈Angular4 脏值检测(性能优化)
Apr 23 Javascript
详解在微信小程序的JS脚本中使用Promise来优化函数处理
Mar 06 Javascript
小程序Request的另类用法详解
Aug 09 Javascript
Layui数据表格判断编辑输入的值,是否为我需要的类型详解
Oct 26 Javascript
在vue中封装的弹窗组件使用队列模式实现方法
Jul 23 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
thinkphp的URL路由规则与配置实例
2014/11/26 PHP
php实现和c#一致的DES加密解密实例
2017/07/24 PHP
PHP大文件分割上传 PHP分片上传
2017/08/28 PHP
JavaScript中的一些定位属性[图解]
2010/07/14 Javascript
Extjs gridpanel 出现横向滚动条问题的解决方法
2011/07/04 Javascript
两个数组去重的JS代码
2013/12/04 Javascript
JavaScript生成的动态下雨背景效果实现方法
2015/02/25 Javascript
Node.js 去掉种子(torrent)文件里的邪恶信息
2015/03/27 Javascript
浅谈$(document)和$(window)的区别
2015/07/15 Javascript
关于js二维数组和多维数组的定义声明(详解)
2016/10/02 Javascript
微信小程序 switch组件详解及简单实例
2017/01/10 Javascript
Vue computed计算属性的使用方法
2017/07/14 Javascript
jQuery实现的鼠标滚轮控制图片缩放功能实例
2017/10/14 jQuery
基于node下的http小爬虫的示例代码
2018/01/11 Javascript
原生JS实现的轮播图功能详解
2018/08/06 Javascript
React 使用Hooks简化受控组件的状态绑定
2019/03/18 Javascript
js实现录音上传功能
2019/11/22 Javascript
由Python运算π的值深入Python中科学计算的实现
2015/04/17 Python
python的keyword模块用法实例分析
2015/06/30 Python
Python3使用requests发闪存的方法
2016/05/11 Python
Python 处理数据的实例详解
2017/08/10 Python
老生常谈Python startswith()函数与endswith函数
2017/09/08 Python
一个月入门Python爬虫学习,轻松爬取大规模数据
2018/01/03 Python
python3 读写文件换行符的方法
2018/04/09 Python
Python爬虫beautifulsoup4常用的解析方法总结
2019/02/25 Python
libreoffice python 操作word及excel文档的方法
2019/07/04 Python
python3实现斐波那契数列(4种方法)
2019/07/15 Python
Python 使用 environs 库定义环境变量的方法
2020/02/25 Python
Pycharm及python安装详细步骤及PyCharm配置整理(推荐)
2020/07/31 Python
CSS3实现背景透明文字不透明的示例代码
2018/06/25 HTML / CSS
澳大利亚最大的女装零售商:Millers
2017/09/10 全球购物
英国领先的维生素和营养补充剂直接供应商:Healthspan
2019/04/22 全球购物
小学运动会报道稿
2014/10/04 职场文书
入党现实表现材料
2014/12/23 职场文书
大足石刻导游词
2015/02/02 职场文书
Python编程源码报错解决方法总结经验分享
2021/10/05 Python