JavaScript深拷贝实现原理简析
原文:http://www.cnblogs.com/xie-zhan/p/6020954.html
JavaScript实现继承的时候,需要进行对象的拷贝;而为了不影响拷贝后的数据对原数据造成影响,也就是存在共享关系的时候,我们就需要进行深拷贝;
这里就做一个简单的分析其实现原理
先上代码:
var obj1 = {
name : 'Awen',
song : {
auther : '小明',
title : '广州'
},
hobby: ['吃','吃吃','吃吃吃']
};
var obj2 = {};
for (var k in obj1) {
obj2[k] = obj1[k];
}
console.log(obj2); //Object {name: "Awen", song: Object, hobby: Array[3]}
obj2['hobby'].push('喝');
console.log(obj1); //Object {name: "Awen", song: Object, hobby: Array[4]}
console.log(obj2); //Object {name: "Awen", song: Object, hobby: Array[4]}
从图中得到结论:浅拷贝不能完成需求,对于属性是对象的时候,只是进行简单的地址拷贝,其引用关系也在;不符合我们的要求;
在来看下深拷贝:
function inCopy(obj1,obj2) {
var obj1 = obj1 || {};//容错处理
for (var k in obj2) {
if(obj2.hasOwnProperty(k)){ //只拷贝实例属性,不进行原型的拷贝
if(typeof obj2[k] == 'object') { //引用类型的数据单独处理
obj1[k] = Array.isArray(obj2[k])?[]:{};
inCopy(obj1[k],obj2[k]); //递归处理引用类型数据
}else{
obj1[k] = obj2[k]; //值类型的数据直接进行拷贝
}
}
}
}
//深拷贝 两者之间改变互不影响
//1 拷贝后两者之间不再存在共享关系
//2 拷贝之后数据类型不能发生改变,也就是需要判断是数组的时候,需要进行单独递归的遍历
//3 在继承的时候,我们通过原型属性实现原型对象属性的继承,在进行深拷贝的时候,我们首先需要提出原型对象上的属性;通过hasOwnProperty方法来进行筛选;
测试代码及结果如下
var obj3 = {
name : 'Awen',
song : {
auther : '小明',
title : '广州'
},
hobby : ['吃','吃吃','吃吃吃']
};
var obj4 = {};
inCopy(obj4,obj3);
console.log(obj3); //Object {name: "Awen", song: Object, hobby: Array[3]}
console.log(obj4); //Object {name: "Awen", song: Object, hobby: Array[3]}
obj4.hobby.pop();
console.log(obj3); //Object {name: "Awen", song: Object, hobby: Array[3]}
console.log(obj4); //Object {name: "Awen", song: Object, hobby: Array[2]}
obj4.song.title = '北京';
console.log(obj3);
console.log(obj4);
obj4动态改变
3 拷贝后数据类型保持一致

数据类型未发生改变
JavaScript深拷贝实现原理简析的更多相关文章
- Java Android 注解(Annotation) 及几个常用开源项目注解原理简析
不少开源库(ButterKnife.Retrofit.ActiveAndroid等等)都用到了注解的方式来简化代码提高开发效率. 本文简单介绍下 Annotation 示例.概念及作用.分类.自定义. ...
- PHP的错误报错级别设置原理简析
原理简析 摘录php.ini文件的默认配置(php5.4): ; Common Values: ; E_ALL (Show all errors, warnings and notices inclu ...
- Java Annotation 及几个常用开源项目注解原理简析
PDF 版: Java Annotation.pdf, PPT 版:Java Annotation.pptx, Keynote 版:Java Annotation.key 一.Annotation 示 ...
- [转载] Thrift原理简析(JAVA)
转载自http://shift-alt-ctrl.iteye.com/blog/1987416 Apache Thrift是一个跨语言的服务框架,本质上为RPC,同时具有序列化.发序列化机制:当我们开 ...
- Spring系列.@EnableRedisHttpSession原理简析
在集群系统中,经常会需要将Session进行共享.不然会出现这样一个问题:用户在系统A上登陆以后,假如后续的一些操作被负载均衡到系统B上面,系统B发现本机上没有这个用户的Session,会强制让用户重 ...
- SIFT特征原理简析(HELU版)
SIFT(Scale-Invariant Feature Transform)是一种具有尺度不变性和光照不变性的特征描述子,也同时是一套特征提取的理论,首次由D. G. Lowe于2004年以< ...
- 基于IdentityServer4的OIDC实现单点登录(SSO)原理简析
写着前面 IdentityServer4的学习断断续续,兜兜转转,走了不少弯路,也花了不少时间.可能是因为没有阅读源码,也没有特别系统的学习资料,相关文章很多园子里的大佬都有涉及,有系列文章,比如: ...
- 【超精简JS模版库/前端模板库】原理简析 和 XSS防范
使用jsp.php.asp或者后来的struts等等的朋友,不一定知道什么是模版,但一定很清楚这样的开发方式: <div class="m-carousel"> < ...
- ARP攻击原理简析及防御措施
0x1 简介 网络欺骗攻击作为一种非常专业化的攻击手段,给网络安全管理者,带来严峻的考验.网络安全的战场已经从互联网蔓延到用户内部的网络, 特别是局域网.目前利用ARP欺骗的木马病毒在局域网中广泛传 ...
随机推荐
- Android性能优化之图片压缩优化
1 分类Android图片压缩结合多种压缩方式,常用的有尺寸压缩.质量压缩.采样率压缩以及通过JNI调用libjpeg库来进行压缩. 参考此方法:Android-BitherCompress 备注:对 ...
- 【翻译】关于vertical-align所有你需要知道的
本文是翻译过来的,如果有不对的地方还请指教~,原文链接:Vertical-Align: All You Need To Know 前面一些说明,可以略过不看吧 我经常需要对元素进行垂直方向上的布局. ...
- 修改html中button显示的文字
1. <input type="button"> 实现密码输入框的可见和隐藏 直接修改value属性即可 <script type="text/jav ...
- Confluence 6 配置避免管理员联系表单垃圾
你可以配置 Confluence 使用验证码(Captcha)来避免垃圾内容发送给 Confluence 管理员.有关管理员联系表单验证码的内容在全站验证码设置中进行配置,相关的文档请参考 Confi ...
- HTML&javaSkcript&CSS&jQuery&ajax(七)
’一.HTML5 实例 <video width="430" controls> <source src="mov_nnn.mp4" t ...
- 把tomcat服务器配置为windows服务的方法
转自:http://ykyfendou.iteye.com/blog/2032916 使用tomcat开发的项目,我们把项目交付给客户的时候,客户都不希望在每次开机的时候都要启动一下tomcat服务器 ...
- JS实现继承的几种方式(转)
转自:幻天芒的博客 前言 JS作为面向对象的弱类型语言,继承也是其非常强大的特性之一.那么如何在JS中实现继承呢?让我们拭目以待. JS继承的实现方式 既然要实现继承,那么首先我们得有一个父类,代码如 ...
- javascript 自动填充功能
javascript 自动填充功能 javascript: (function(){ $("#zipcode").val("zip");$("#pho ...
- MySQL修改数据表存储引擎的3种方法介绍
这篇文章主要介绍了MySQL修改数据表存储引擎的3种方法介绍,分别是直接修改.导出导入.创建插入3种方法, 可以参考下 MySQL作为最常用的数据库,经常遇到各种各样的问题.今天要说的就是表存储引 ...
- Python函数之内置函数
截止导Python 3.6 目前内置函数有68个 以下是对这些内置函数的分类 一:作用域相关 以字典的形式返回作用域中的名字 locals # 返回本地作用域的所有名字 globals # 返回全局作 ...