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 相关文章推荐
iframe 父窗口和子窗口相互的调用方法集锦
Dec 15 Javascript
javascript学习笔记(四) Number 数字类型
Jun 19 Javascript
基于JavaScript实现继承机制之调用call()与apply()的方法详解
May 07 Javascript
js 处理数组重复元素示例代码
Dec 27 Javascript
JavaScript基础函数整理汇总
Jan 30 Javascript
jquery中EasyUI实现同步树
Mar 01 Javascript
js实现具有高亮显示效果的多级菜单代码
Sep 01 Javascript
JQuery中attr属性和jQuery.data()学习笔记【必看】
May 18 Javascript
利用jQuery实现打字机字幕效果实例代码
Sep 02 Javascript
Vue.js在使用中的一些注意知识点
Apr 29 Javascript
Vue自定义指令实现checkbox全选功能的方法
Feb 28 Javascript
angularjs中判断ng-repeat是否迭代完的实例
Sep 12 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上传apk后自动提取apk包信息的使用(示例下载)
2013/04/26 PHP
php根据分类合并数组的方法实例详解
2013/11/06 PHP
CodeIgniter框架中_remap()使用方法2例
2014/03/10 PHP
PHP SPL标准库之接口(Interface)详解
2015/05/11 PHP
laravel-admin的图片删除实例
2019/09/30 PHP
PHP pthreads v3下同步处理synchronized用法示例
2020/02/21 PHP
jQuery中文入门指南,翻译加实例,jQuery的起点教程
2007/02/09 Javascript
js apply/call/caller/callee/bind使用方法与区别分析
2009/10/28 Javascript
javascript下arguments,caller,callee,call,apply示例及理解
2009/12/24 Javascript
jQuery的slideToggle方法实例
2013/05/07 Javascript
教你如何在 Javascript 文件里使用 .Net MVC Razor 语法
2014/07/23 Javascript
分享一款基于jQuery的视频播放插件
2014/10/09 Javascript
了不起的node.js读书笔记之node的学习总结
2014/12/22 Javascript
JavaScript实现搜索框的自动完成功能(一)
2016/02/25 Javascript
jQuery页面元素动态添加后绑定事件丢失方法,非 live
2016/06/16 Javascript
vue分页组件table-pagebar使用实例解析
2020/11/15 Javascript
js给table赋值的实例代码
2016/10/13 Javascript
jQuery插件实现的日历功能示例【附源码下载】
2018/09/07 jQuery
vue中js判断长时间不操作界面自动退出登录(推荐)
2020/01/22 Javascript
Vue和React有哪些区别
2020/09/12 Javascript
读写json中文ASCII乱码问题的解决方法
2016/11/05 Python
python如何使用正则表达式的前向、后向搜索及前向搜索否定模式详解
2017/11/08 Python
11个Python3字典内置方法大全与示例汇总
2019/05/13 Python
使用python实现飞机大战游戏
2020/03/23 Python
动态设置django的model field的默认值操作步骤
2020/03/30 Python
python+selenium+chrome批量文件下载并自动创建文件夹实例
2020/04/27 Python
CSS实现鼠标滑过鼠标点击代码写法
2016/12/26 HTML / CSS
小车司机岗位职责
2013/11/25 职场文书
电子商务专业自我鉴定
2013/12/18 职场文书
治超工作实施方案
2014/05/04 职场文书
村容村貌整治方案
2014/05/21 职场文书
安全标语口号
2014/06/09 职场文书
2014年转正工作总结
2014/11/08 职场文书
2015年反腐倡廉工作总结
2015/05/14 职场文书
初中英语教学随笔
2015/08/15 职场文书
Python序列化模块JSON与Pickle
2022/06/05 Python