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弹性滑动导航菜单实现思路及代码
May 02 Javascript
JQuery选中checkbox方法代码实例(全选、反选、全不选)
Apr 27 Javascript
基于jQuey实现鼠标滑过变色(整行变色)
Dec 07 Javascript
SpringMVC返回json数据的三种方式
Dec 10 Javascript
基于JavaScript代码实现微信扫一扫下载APP
Dec 30 Javascript
jquery实现下拉框功能效果【实例代码】
May 06 Javascript
jquery根据一个值来选中select下的option实例代码
Aug 29 Javascript
vue组件之Alert的实现代码
Oct 17 Javascript
vue keep-alive请求数据的方法示例
May 16 Javascript
几个你不知道的技巧助你写出更优雅的vue.js代码
Jun 11 Javascript
vue-cli webpack配置文件分析
May 20 Javascript
ES6 Promise对象概念及用法实例详解
Oct 15 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实现最简单的MVC框架实例教程
2014/09/08 PHP
Yii2框架自定义验证规则操作示例
2019/02/08 PHP
实例介绍PHP删除数组中的重复元素
2019/03/03 PHP
因str_replace导致的注入问题总结
2019/08/08 PHP
PHP+Redis事务解决高并发下商品超卖问题(推荐)
2020/08/03 PHP
[转]JS宝典学习笔记
2007/02/07 Javascript
JavaScript 定义function的三种方式小结
2009/10/16 Javascript
jquery异步请求实例代码
2011/06/21 Javascript
关于JavaScript的面向对象和继承有利新手学习
2013/01/11 Javascript
JS对文本框值的判断示例
2014/03/10 Javascript
JS组件Bootstrap Table表格行拖拽效果实现代码
2020/08/27 Javascript
使用JavaScript脚本判断页面是否在微信中被打开
2016/03/06 Javascript
基于JavaScript代码实现自动生成表格
2016/06/15 Javascript
angularJs关于指令的一些冷门属性详解
2016/10/24 Javascript
JS实现的相册图片左右滚动完整实例
2016/11/23 Javascript
Express与NodeJs创建服务器的两种方法
2017/02/06 NodeJs
require.js与bootstrap结合实现简单的页面登录和页面跳转功能
2017/05/12 Javascript
Node.js中的cluster模块深入解读
2018/06/11 Javascript
详解超简单的react服务器渲染(ssr)入坑指南
2019/02/28 Javascript
Python的Socket编程过程中实现UDP端口复用的实例分享
2016/03/19 Python
Python检测网络延迟的代码
2018/05/15 Python
python实现画循环圆
2019/11/23 Python
Python基于Tensor FLow的图像处理操作详解
2020/01/15 Python
Python3连接Mysql8.0遇到的问题及处理步骤
2020/02/17 Python
如何使用pandas读取txt文件中指定的列(有无标题)
2020/03/05 Python
python 使用cycle构造无限循环迭代器
2020/12/02 Python
CAT鞋英国官网:坚固耐用的靴子和鞋
2016/10/21 全球购物
海滩咖啡馆:Beach Cafe
2018/02/02 全球购物
澳大利亚领先的在线药房:Pharmacy Online(有中文站)
2020/02/22 全球购物
说出你对remoting 和webservice的理解和应用
2014/06/08 面试题
培训主管的职业生涯规划
2014/03/06 职场文书
合作协议书怎么写
2014/04/18 职场文书
计算机科学技术自荐信
2014/06/12 职场文书
英文演讲稿开场白
2014/08/25 职场文书
对外汉语专业大学生职业生涯规划范文
2014/09/13 职场文书
先进党组织事迹材料
2014/12/26 职场文书