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 ondocumentready onmouseover onclick onmouseout 样式
Jul 22 Javascript
JavaScript高级程序设计阅读笔记(五) ECMAScript中的运算符(一)
Feb 27 Javascript
js实现特定位取反原理及示例
Jun 30 Javascript
jQuery中extend函数详解
Feb 13 Javascript
基于JQuery实现图片轮播效果(焦点图)
Feb 02 Javascript
一览画面点击复选框后获取多个id值的方法
May 30 Javascript
JavaScript toUpperCase()方法使用详解
Aug 26 Javascript
AngularJS constant和value区别详解
Feb 28 Javascript
vue与TypeScript集成配置最简教程(推荐)
Oct 17 Javascript
小程序自定义组件实现城市选择功能
Jul 18 Javascript
浅谈JavaScript_DOM学习篇_图片切换小案例
Mar 19 Javascript
Vue项目打包压缩的实现(让页面更快响应)
Mar 10 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
mysql5写入和读出乱码解决
2006/11/25 PHP
PHP Mysql编程之高级技巧
2008/08/27 PHP
PHP结合jQuery.autocomplete插件实现输入自动完成提示的功能
2015/04/27 PHP
javascript学习笔记(七) js函数介绍
2012/06/19 Javascript
js数值和和字符串进行转换时可以对不同进制进行操作
2014/03/05 Javascript
javascript实现checkbox全选的代码
2015/04/30 Javascript
JavaScript进阶练习及简单实例分析
2016/06/03 Javascript
jQuery实现鼠标选中文字后弹出提示窗口效果【附demo源码】
2016/09/05 Javascript
微信小程序 详解下拉加载与上拉刷新实现方法
2017/01/13 Javascript
jQuery Validation Engine验证控件调用外部函数验证的方法
2017/01/18 Javascript
vue刷新和tab切换实例
2018/02/11 Javascript
Angular 2使用路由自定义弹出组件toast操作示例
2019/05/10 Javascript
js中arguments对象的深入理解
2019/05/14 Javascript
移动端手指操控左右滑动的菜单
2019/09/08 Javascript
vue-cli中实现响应式布局的方法
2021/03/02 Vue.js
Python通过正则表达式选取callback的方法
2015/07/18 Python
TensorFlow模型保存和提取的方法
2018/03/08 Python
Python实现的合并两个有序数组算法示例
2019/03/04 Python
解决python 执行shell命令无法获取返回值的问题
2020/12/05 Python
利用三角函数在canvas上画虚线的方法
2018/01/11 HTML / CSS
HTML5自定义元素播放焦点图动画的实现
2019/09/25 HTML / CSS
资生堂英国官网:Shiseido英国
2020/12/30 全球购物
管理学专业个人求职信范文
2013/09/21 职场文书
日语翻译个人求职的自我评价
2013/10/14 职场文书
医院门卫岗位职责
2013/12/30 职场文书
财务会计专业求职信范文
2013/12/31 职场文书
单位消防安全制度
2014/01/12 职场文书
新郎婚宴答谢词
2014/01/19 职场文书
汽车专业求职信
2014/06/05 职场文书
党员批评与自我批评(5篇)
2014/09/23 职场文书
超级实用的公文标题大全!
2019/07/19 职场文书
二手手机买卖合同范本(2019年版)
2019/10/28 职场文书
PostgreSQL将数据加载到buffer cache中操作方法
2021/04/16 PostgreSQL
JS如何使用剪贴板操作Clipboard API
2021/05/17 Javascript
Python中的变量与常量
2021/11/11 Python
Android移动应用开发指南之六种布局详解
2022/09/23 Java/Android