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 相关文章推荐
window.location.hash 属性使用说明
Mar 20 Javascript
JQuery调用绑定click事件的3种写法
Mar 28 Javascript
js实现input框文字动态变换显示效果
Aug 19 Javascript
jQuery Uploadify 上传插件出现Http Error 302 错误的解决办法
Dec 12 Javascript
Bootstrap~多级导航(级联导航)的实现效果【附代码】
Mar 08 Javascript
jQuery toggle 代替方法
Mar 22 Javascript
AngularJS框架中的双向数据绑定机制详解【减少需要重复的开发代码量】
Jan 19 Javascript
JavaWeb表单及时验证功能在输入后立即验证(含用户类型,性别,爱好...的验证)
Jun 09 Javascript
深入理解Vue官方文档梳理之全局API
Nov 22 Javascript
微信小程序签到功能
Oct 31 Javascript
Vue 前端实现登陆拦截及axios 拦截器的使用
Jul 17 Javascript
jQuery实现带进度条的轮播图
Sep 13 jQuery
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
FCKeditor添加自定义按钮
2008/03/27 PHP
Warning: session_destroy() : Trying to destroy uninitialized sessionq错误
2011/06/16 PHP
PHP正则提取不包含指定网址的图片地址的例子
2014/04/21 PHP
laravel安装和配置教程
2014/10/29 PHP
java模拟PHP的pack和unpack类
2016/04/13 PHP
ThinkPHP打水印及设置水印位置的方法
2016/10/14 PHP
php实现的简单数据库操作Model类
2016/11/16 PHP
PHP使用微信开发模式实现搜索已发送图文及匹配关键字回复的方法
2017/09/13 PHP
JavaScript页面刷新与弹出窗口问题的解决方法
2010/03/02 Javascript
IE本地存储userdata的一个bug说明
2010/07/01 Javascript
JavaScript中使用构造器创建对象无需new的情况说明
2012/03/01 Javascript
JavaScript中的关键字&quot;VAR&quot;使用详解 分享
2013/07/31 Javascript
jQuery中appendTo()方法用法实例
2015/01/08 Javascript
漫谈JS引擎的运行机制 你应该知道什么
2016/06/15 Javascript
AngularJs bootstrap搭载前台框架——js控制部分
2016/09/01 Javascript
vue.js入门(3)——详解组件通信
2016/12/02 Javascript
JavaScript使用正则表达式获取全部分组内容的方法示例
2017/01/17 Javascript
JQuery validate 验证一个单独的表单元素实例
2017/02/17 Javascript
详解element-ui中表单验证的三种方式
2019/09/18 Javascript
js点击事件的执行过程实例分析【冒泡与捕获】
2020/04/11 Javascript
Javascript实现鼠标移入方向感知
2020/06/24 Javascript
ajax jquery实现页面某一个div的刷新效果
2021/03/04 jQuery
[41:17]完美世界DOTA2联赛PWL S3 access vs CPG 第二场 12.13
2020/12/17 DOTA
python正则表达式中的括号匹配问题
2014/12/14 Python
pip install urllib2不能安装的解决方法
2018/06/12 Python
Django框架自定义session处理操作示例
2019/05/27 Python
HTML5中input输入框默认提示文字向左向右移动的示例代码
2020/09/10 HTML / CSS
阿根廷网上配眼镜:SmartBuyGlasses阿根廷
2016/08/19 全球购物
LEGO玩具英国官方商店:LEGO Shop GB
2018/03/27 全球购物
中科软笔试题和面试题
2014/10/07 面试题
如何写一封打动人心的求职信
2014/02/17 职场文书
高中军训感言400字
2014/02/24 职场文书
安全标兵事迹材料
2014/08/17 职场文书
某集团股份有限公司委托书样本
2014/09/24 职场文书
python基础之文件处理知识总结
2021/05/23 Python
MYSQL 无法识别中文的永久解决方法
2021/06/03 MySQL