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 DOM 学习第九章 选取范围的介绍
Feb 19 Javascript
javascript/jquery获取地址栏url参数的方法
Mar 05 Javascript
JQuery实现样式设置、追加、移除与切换的方法
Jun 11 Javascript
javascript实现二级级联菜单的简单制作
Nov 19 Javascript
js倒计时显示实例
Dec 11 Javascript
ES6新特性六:promise对象实例详解
Apr 21 Javascript
Angular.js中window.onload(),$(document).ready()的写法浅析
Sep 28 Javascript
解决使用vue.js路由后失效的问题
Mar 17 Javascript
vue自动化路由的实现代码
Sep 30 Javascript
es6中使用map简化复杂条件判断操作实例详解
Feb 19 Javascript
JavaScript装饰者模式原理与用法实例详解
Mar 09 Javascript
关于element的表单组件整理笔记
Feb 05 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
Codeigniter中mkdir创建目录遇到权限问题和解决方法
2014/07/25 PHP
PHP实现链式操作的核心思想
2015/06/23 PHP
全面解读PHP的人气开发框架Laravel
2015/10/15 PHP
WordPress中注册菜单与调用菜单的方法详解
2015/12/18 PHP
PHP快速生成各种信息提示框的方法
2016/02/03 PHP
PHP输出多个元素的排列或组合的方法
2017/03/14 PHP
jQuery学习4 浏览器的事件模型
2010/02/07 Javascript
jquery ajax对特殊字符进行转义防止js注入使用示例
2013/11/21 Javascript
禁用JavaScript控制台调试的方法
2014/03/07 Javascript
js实现鼠标触发图片抖动效果的方法
2015/02/27 Javascript
jQuery获得指定元素坐标的方法
2015/04/14 Javascript
javascript实现table选中的行以指定颜色高亮显示的方法
2015/05/13 Javascript
微信小程序 Flex布局详解
2016/10/09 Javascript
nodejs基础知识
2017/02/03 NodeJs
浅谈angularJS的$watch失效问题的解决方案
2017/08/11 Javascript
vue打包后显示空白正确处理方法
2017/11/01 Javascript
vue实现的下拉框功能示例
2019/01/29 Javascript
JS sort方法基于数组对象属性值排序
2020/07/10 Javascript
一篇超完整的Vue新手入门指导教程
2020/11/18 Vue.js
Python中用startswith()函数判断字符串开头的教程
2015/04/07 Python
Python队列的定义与使用方法示例
2017/06/24 Python
python微信跳一跳系列之棋子定位颜色识别
2018/02/26 Python
Matplotlib 生成不同大小的subplots实例
2018/05/25 Python
实例讲解python中的协程
2018/10/08 Python
python多线程+代理池爬取天天基金网、股票数据过程解析
2019/08/13 Python
使用django和vue进行数据交互的方法步骤
2019/11/11 Python
Python 私有化操作实例分析
2019/11/21 Python
详解python内置模块urllib
2020/09/09 Python
挪威太阳镜和眼镜网上商城:SmartBuyGlasses挪威
2016/08/20 全球购物
台湾前三大B2C购物网站:MOMO购物网
2017/04/27 全球购物
豪华复古化妆:Besame Cosmetics
2019/09/06 全球购物
职业生涯规划书前言
2014/04/15 职场文书
安全施工责任书
2014/08/25 职场文书
反对四风问题自我剖析材料
2014/09/29 职场文书
2014年保安个人工作总结
2014/11/13 职场文书
JUnit5常用注解的使用
2021/07/02 Java/Android