js对象的深浅拷贝
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对象的深浅拷贝的更多相关文章
- js中的深浅拷贝
js中的深浅拷贝 js中有深拷贝.浅拷贝一说,所谓的深浅拷贝是针对value类型为引用类型(函数.对象.数组)而言的,大概理解的就是: 浅拷贝: 拷贝出的对象c和原始对象o,c和o在key对应的val ...
- 关于Java的Object.clone()方法与对象的深浅拷贝
文章同步更新在个人博客:关于Java的Object.clone()方法与对象的深浅拷贝 引言 在某些场景中,我们需要获取到一个对象的拷贝用于某些处理.这时候就可以用到Java中的Object.clon ...
- 【 js 基础 】 深浅拷贝
underscore的源码中,有很多地方用到了 Array.prototype.slice() 方法,但是并没有传参,实际上只是为了返回数组的副本,例如 underscore 中 clone 的方法: ...
- JS复习之深浅拷贝
一.复习导论(数据类型相关) 想掌握JS的深浅拷贝,首先来回顾一下JS的数据类型,JS中数据类型分为基本数据类型和引用数据类型. 基本数据类型是指存放在栈中的简单数据段,数据大小确定,内存空间大小可以 ...
- 超实用的JavaScript代码段 Item8 -- js对象的(深)拷贝
js 对象 浅拷贝 和 深拷贝 1.浅拷贝 拷贝就是把父对像的属性,全部拷贝给子对象. 下面这个函数,就是在做拷贝: var Chinese = { nation:'中国' } var Doctor ...
- Object.clone()方法与对象的深浅拷贝
转载:[https://www.cnblogs.com/nickhan/p/8569329.html] 引言 在某些场景中,我们需要获取到一个对象的拷贝用于某些处理.这时候就可以用到Java中的Obj ...
- js对象的深度拷贝
//判断对象的类型 Array Object Function String Number ..... function getObjType(obj){ return Object.prototyp ...
- 总结JavaScript对象的深浅拷贝
十四.对象的浅拷贝与深拷贝 什么是对象的拷贝? 将一个对象赋值给另外一个对象, 我们称之为对象的拷贝 什么是深拷贝, 什么是浅拷贝? 我们假设将A对象赋值给B对象 浅拷贝是指, 修改B对象的属性和方法 ...
- js对象深潜拷贝(从requirejs中抠出来的)
var op = Object.prototype, ostring = op.toString, hasOwn = op.hasOwnProperty; function isFunction(it ...
随机推荐
- SpringBoot JPA 中无法注入 JpaRepository 接口的问题及解决方案
错误: 在Springboot 框架中使用JPA的过程中,怎么来实现数据库操作底层的交互呢?Spring JPA其实已经提供了一套很全面的解决方案,实现对数据库的增.删.查.改只需要继承JPA实现类 ...
- rails 自定义校验及validates_each多校验
一.自定义校验 使用 validate 方法传入一个同名方法的 Symbol 即可. validate :my_validation private def my_validation if name ...
- Oracle 多表查询(2)
四.统计函数及分组查询 1.统计函数 在之前学习过一个COUNT()函数,此函数的功能可以统计出表中的数据量,实际上这个就是一个统计函数,而常用的统计函数有如下几个: COUNT():查询表中的数据记 ...
- springmvc----demo1---hello---bai
import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import ...
- Android逆向基础知识Smali
什么是Smali: 我们用工具反编译一些APP的时候,会看到一个smali文件夹,里面其实就是每个Java类所对应的smali文件.Android虚拟机Dalvik并不是执行java虚拟机JVM编译后 ...
- 微信小程序基础语法总结
本文介绍微信小程序语法 配置文件 app.json的配置(全局) { // 用来配置页面的路径 "pages":[ "pages/index/index", / ...
- 2016.2.28 DataTable用法汇总
将控件的DataSource转换为DataTable,但是,此控件的DataSource绑定时必须是DataTable,不能是List DataTable dt = (bgvRoutePortion. ...
- NodeJs之项目构建(对文件及文件夹的操作)
前提:需要使用:require('fs')引入外部模块 简单的模仿创建一个文件下有多个文件. 首先,准备一个主文件夹 然后,准备放在这个主文件夹下的文件加 在代码中通过对象,数字,json对象来装 代 ...
- 10-16C#for...循环语句(2)
for....循环语句 格式:for(初始条件:循环条件:状态改变) { 循环体: } 一.课前作业:打印等腰直角三角形 第一种方法:是运用一开始学习的从上往下执行控制台程序,用一个for循环语句执行 ...
- C#调用带返回值的存储过程
()在SQL Server中建立如下的存储过程: set ANSI_NULLS ON set QUOTED_IDENTIFIER ON GO CREATE PROCEDURE [dbo].[GetNa ...