JS数据类型可以分为(ES5,暂时不考虑ES6):

  简单数据类型:Number、String、undefined、boolean

  复杂数据类型:Object、Array

简单的数据类型,往往是赋值操作,而复杂数据类型是引用操作。

赋值操作我们就不讲了,主要看看引用操作把

    var arr = [1,2,3];
var arr2 = arr;
arr2.push(4);
console.log(arr);//输出[1,2,3,4]

明明是对arr2进行的操作,为什么arr也变化了呢?因为js存储对象都是存地址的,所以arr2实际存储的是:"arr在内存中的地址";

由此我们可以明白,既然都是指向同一个内存地址,当我们改变任何一个的时候,都会改变。

知道这个基本的特性那么我们可以试图来理解下浅复制和深复制

首先看一段代码,我们再来讲解下概念

    var obj ={a:1,b:2,c:[1,2]};
var shallowCopy = shallow(obj);
function shallow(obj){
var shallowObj = {};
for(var name in obj){
if(obj.hasOwnProperty(name)){
shallowObj[name] = obj[name]
}
}
return shallowObj
}
console.log(shallowCopy);//输出的就是这个对象,我们实现了简单的浅复制;

浅复制:只会将对象的各个属性进行依次复制,并不会进行递归复制,而js存储对象都是存地址的,所以浅复制会导致obj.c和shallowCopy.c 指向同一块内存地址;会导致引用。

深复制:它不仅将原对象的各个属性逐个复制出去,而且将原对象各个属性所包含的对象也依次采用深复制的方法递归复制到新对象上。这就不会存在上面obj和shallowCopy的c属性指向同一个对象的问题。(待会贴出深复制的代码,这是个复杂的问题)

总结:需要注意的是,如果对象比较大,层级也比较多,深复制会带来性能上的问题。在遇到需要采用深复制的场景时,可以考虑有没有其他替代方案,在实际的引用场景中,也是浅复制更为常用。

我现在给出一个简单版本的深复制,可以复制对象和数组(不考虑循环引用问题,函数对象问题),如果想深入研究的话可以看下这篇文章:http://jerryzou.com/posts/dive-into-deep-clone-in-javascript/

在这里我们只理解思想和简单的实现,实际项目中可以考虑使用lodash(http://lodashjs.com/docs/),或者jQuery的extend的方法也同样可以

    function deepClone(obj){
var newObj = obj.constructor === Array ? []:{};
if(typeof obj !== 'object'){
return
}else{
for(var i in obj){
if(obj.hasOwnProperty(i)){
newObj[i] = typeof obj[i] === 'object'?deepClone(obj[i]):obj[i];
}
}
}
return newObj
}

最核心的思想还是采用递归的方式,不断进行,直到基本数据类型后,再复制

方法还有很多种,譬如还有使用JSON.stringify进行序列化,JSON.parse进行反序列化,实现"偷懒版"的深复制...等等

js对象的深浅拷贝的更多相关文章

  1. js中的深浅拷贝

    js中的深浅拷贝 js中有深拷贝.浅拷贝一说,所谓的深浅拷贝是针对value类型为引用类型(函数.对象.数组)而言的,大概理解的就是: 浅拷贝: 拷贝出的对象c和原始对象o,c和o在key对应的val ...

  2. 关于Java的Object.clone()方法与对象的深浅拷贝

    文章同步更新在个人博客:关于Java的Object.clone()方法与对象的深浅拷贝 引言 在某些场景中,我们需要获取到一个对象的拷贝用于某些处理.这时候就可以用到Java中的Object.clon ...

  3. 【 js 基础 】 深浅拷贝

    underscore的源码中,有很多地方用到了 Array.prototype.slice() 方法,但是并没有传参,实际上只是为了返回数组的副本,例如 underscore 中 clone 的方法: ...

  4. JS复习之深浅拷贝

    一.复习导论(数据类型相关) 想掌握JS的深浅拷贝,首先来回顾一下JS的数据类型,JS中数据类型分为基本数据类型和引用数据类型. 基本数据类型是指存放在栈中的简单数据段,数据大小确定,内存空间大小可以 ...

  5. 超实用的JavaScript代码段 Item8 -- js对象的(深)拷贝

    js 对象 浅拷贝 和 深拷贝 1.浅拷贝 拷贝就是把父对像的属性,全部拷贝给子对象. 下面这个函数,就是在做拷贝: var Chinese = { nation:'中国' } var Doctor ...

  6. Object.clone()方法与对象的深浅拷贝

    转载:[https://www.cnblogs.com/nickhan/p/8569329.html] 引言 在某些场景中,我们需要获取到一个对象的拷贝用于某些处理.这时候就可以用到Java中的Obj ...

  7. js对象的深度拷贝

    //判断对象的类型 Array Object Function String Number ..... function getObjType(obj){ return Object.prototyp ...

  8. 总结JavaScript对象的深浅拷贝

    十四.对象的浅拷贝与深拷贝 什么是对象的拷贝? 将一个对象赋值给另外一个对象, 我们称之为对象的拷贝 什么是深拷贝, 什么是浅拷贝? 我们假设将A对象赋值给B对象 浅拷贝是指, 修改B对象的属性和方法 ...

  9. js对象深潜拷贝(从requirejs中抠出来的)

    var op = Object.prototype, ostring = op.toString, hasOwn = op.hasOwnProperty; function isFunction(it ...

随机推荐

  1. 生产者与消费者---demo2---boke

    假设有这样一种情况,有一个桌子,桌子上面有一个盘子,盘子里只能放一颗鸡蛋,A专门往盘子里放鸡蛋,如果盘子里有鸡蛋,则一直等到盘子里没鸡蛋,B专门从盘子里拿鸡蛋,如果盘子里没鸡蛋,则等待直到盘子里有鸡蛋 ...

  2. 应用HTMLTestRunner整合测试报告

    为了便于测试脚本的维护,以及更多测试用例的管理,于是根据上次学习的HTMLTestRunner生成的测试报告,今天将对其进行整理.我们之前使用 TestSuite 只是在一个.py 文件里添加多个测试 ...

  3. 2016.8.11 DataTable合并及排除重复方法

    合并: DataTable pros=xxx; DataTable pstar=yyy; //将两张DataTable合成一张 foreach (DataRow dr in pstar.Rows) { ...

  4. windows下基于bat的每1分钟执行一次一个程序

    @echo off cls mode con cols=35 lines=6 & color 5B :p call python C:\省局监控\ahwater_perf_monitor.py ...

  5. NT AUTHORITY\IUSR登录失败解决方法

    NT AUTHORITY\IUSR登录失败解决方法 1 今天打开网站时,突然报这个错误,平时都好好的 Cannot open database "aslkm" requested ...

  6. docker 笔记 (6)搭建本地registry

    转:http://blog.csdn.net/felix_yujing/article/details/51564739 新版 registry v2对镜像存储格式进行了重新设计,并且和旧版还不兼容. ...

  7. day35-hibernate映射 03-Hibernate持久态对象自动更新数据库

    持久态对象一个非常重要的能力:自动更新数据库. package cn.itcast.hibernate3.demo1; import static org.junit.Assert.*; import ...

  8. oracle创建完实例删除的时候报ORA-01031:insufficient privileges错误,解决办法

    创建了一个数据库,想删除确报了一个ORA-01031:insufficient privileges错误 查了好久,总算解决了,原因是我的电脑登录账户不在ORA_DBA系统群组中,添加进去完美删除! ...

  9. Codeforces 1137C Museums Tour (强连通分量, DP)

    题意和思路看这篇博客就行了:https://www.cnblogs.com/cjyyb/p/10507937.html 有个问题需要注意:对于每个scc,只需要考虑进入这个scc的时间即可,其实和从哪 ...

  10. nginx关闭php报错页面显示

    默认情况下nginx是会显示php的报错的,如果要关闭报错显示,需要在/usr/local/php7/etc/php-fpm.d/www.conf文件里面设置,貌似默认情况下在php.ini关闭没效果 ...