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 BS,dialog控件自适应大小
Jul 06 Javascript
jQuery 源码分析笔记(7) Queue
Jun 19 Javascript
js复制网页内容并兼容各主流浏览器的代码
Dec 17 Javascript
Chrome下ifame父窗口调用子窗口的问题示例探讨
Mar 17 Javascript
原生js获取浏览器窗口及元素宽高常用方法集合
Jan 18 Javascript
基于Bootstrap 3 JQuery及RegExp的表单验证功能
Feb 16 Javascript
老生常谈Bootstrap媒体对象
Jul 06 Javascript
vue-cli结合Element-ui基于cropper.js封装vue实现图片裁剪组件功能
Mar 01 Javascript
React路由管理之React Router总结
May 10 Javascript
Element Dropdown下拉菜单的使用方法
Jul 26 Javascript
AJAX XMLHttpRequest对象创建使用详解
Aug 20 Javascript
vue 修改 data 数据问题并实时显示操作
Sep 07 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 fopen()和 file_get_contents()应用与差异介绍
2014/03/19 PHP
Yii2下点击验证码的切换实例代码
2017/03/14 PHP
PHP使用数组实现矩阵数学运算的方法示例
2017/05/29 PHP
Jquery响应回车键直接提交表单操作代码
2014/07/25 Javascript
jQuery动态效果显示人物结构关系图的方法
2015/05/07 Javascript
浅谈JavaScript字符串与数组
2015/06/03 Javascript
JavaScript简单下拉菜单实例代码
2015/09/07 Javascript
javascript判断网页是关闭还是刷新
2015/09/12 Javascript
jquery.validate提示错误信息位置方法
2016/01/22 Javascript
vuejs通过filterBy、orderBy实现搜索筛选、降序排序数据
2020/10/26 Javascript
JS之if语句对接事件动作逻辑(详解)
2017/06/28 Javascript
基于EasyUI的基础之上实现树形功能菜单
2017/06/28 Javascript
vue项目base64字符串转图片的实现代码
2018/07/13 Javascript
对Vue2 自定义全局指令Vue.directive和指令的生命周期介绍
2018/08/30 Javascript
解决vue axios的封装 请求状态的错误提示问题
2018/09/25 Javascript
利用vue重构有赞商城的思路以及总结整理
2019/02/21 Javascript
JQuery Ajax跨域调用和非跨域调用问题实例分析
2019/04/16 jQuery
一些可能会用到的Node.js面试题
2019/06/15 Javascript
vue将文件/图片批量打包下载zip的教程
2020/10/21 Javascript
详解微信小程序轨迹回放实现及遇到的坑
2021/02/02 Javascript
复制粘贴功能的Python程序
2008/04/04 Python
深入解析Python中的__builtins__内建对象
2016/06/21 Python
python 自动重连wifi windows的方法
2018/12/18 Python
Python常用的json标准库
2019/02/19 Python
详解用Python实现自动化监控远程服务器
2019/05/18 Python
python实现网站微信登录的示例代码
2019/09/18 Python
pip安装tensorflow的坑的解决
2020/04/19 Python
html5文字阴影效果text-shadow使用示例
2013/07/25 HTML / CSS
HTML5拖拽API经典实例详解
2018/04/20 HTML / CSS
英国的潮牌鞋履服饰商店:size?
2019/03/26 全球购物
实习生个人找工作的自我评价
2013/10/30 职场文书
《狼》教学反思
2014/03/02 职场文书
党旗在我心中演讲稿
2014/09/15 职场文书
八年级作文之一起的走过日子
2019/09/17 职场文书
教你使用Pandas直接核算Excel中快递费用
2021/05/12 Python
python模块与C和C++动态库相互调用实现过程示例
2021/11/02 Python