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. 操作Oracle 一条龙

    1 引用Oracle.DataAccess.dll 2 App.Config中配置连接字符串: Data Source=(DESCRIPTION = (ADDRESS = (PROTOCOL = TC ...

  2. Ubuntu bash不记录history方法

    很多都是用: unset HISTORY HISTFILE HISTSAVE HISTZONE HISTORY HISTLOG export HISTFILE=/dev/null export HIS ...

  3. Eclipse一步一步搭建SSM+Maven

          Eclipse 搭建SSM(Spring.Spring MVC .Mybatis)  利用Maven管理Jar包      一般而言,新的eclipse都已经集成了maven,如果没有那么 ...

  4. CMake 使用方法 & CMakeList.txt<转>

    CMake 使用方法 & CMakeList.txt cmake 简介 CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程).他能够输出各种各样的make ...

  5. 用于.NET环境的时间测试(转)

    用于.NET环境的时间测试   在.NET环境中,衡量运行完整算法所花费的时间长度,需要考虑很多 需要考虑很多种情况 ,如:程序运行所处的线程以及无用单位收集(GC垃圾回收). 在程序执行过程中无用单 ...

  6. GSON 报错HibernateProxy. Forgot to register a type adapter? 的解决办法

    使用Gson转换hibernate对象遇到一个问题,当对象的Lazy加载的,就会出现上面的错误.处理方式摘抄自网上,留存一份以后自己看. 网上找到的解决办法,首先自定义一个类继承TypeAdapter ...

  7. Ros问题汇总

    1.ImportError: No module named beginner_tutorials.srv 解决: cd ~/catkin_ws $ source devel/setup.bash $ ...

  8. gitlab 添加ssh秘钥

    在创建新的ssh秘钥对之前,要先确认一下电脑中是否已经有了一对秘钥: Git Bash on Windows / GNU/Linux / macOS / PowerShell: cat ~/.ssh/ ...

  9. Linux tput命令

    一.简介 shell 脚本编写者往往需要能通过一种方法将输出更改为粗体,为其加下划线,实现反向突出显示等,这正是 tput 的用武之地. tput 命令将通过 terminfo 数据库对您的终端会话进 ...

  10. Evil Book -- CodeChef

    传送门 分析 对于这道题,我们首先思考一个贪心策略,即对于所有我们要打败的厨师我们肯定可以先打败需使用帮助次数少的厨师再打败需使用帮助次数多的厨师 ,因为这样可以使得能支付得起帮助费用的可能性尽可能的 ...