原文: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深拷贝实现原理简析的更多相关文章

  1. Java Android 注解(Annotation) 及几个常用开源项目注解原理简析

    不少开源库(ButterKnife.Retrofit.ActiveAndroid等等)都用到了注解的方式来简化代码提高开发效率. 本文简单介绍下 Annotation 示例.概念及作用.分类.自定义. ...

  2. PHP的错误报错级别设置原理简析

    原理简析 摘录php.ini文件的默认配置(php5.4): ; Common Values: ; E_ALL (Show all errors, warnings and notices inclu ...

  3. Java Annotation 及几个常用开源项目注解原理简析

    PDF 版: Java Annotation.pdf, PPT 版:Java Annotation.pptx, Keynote 版:Java Annotation.key 一.Annotation 示 ...

  4. [转载] Thrift原理简析(JAVA)

    转载自http://shift-alt-ctrl.iteye.com/blog/1987416 Apache Thrift是一个跨语言的服务框架,本质上为RPC,同时具有序列化.发序列化机制:当我们开 ...

  5. Spring系列.@EnableRedisHttpSession原理简析

    在集群系统中,经常会需要将Session进行共享.不然会出现这样一个问题:用户在系统A上登陆以后,假如后续的一些操作被负载均衡到系统B上面,系统B发现本机上没有这个用户的Session,会强制让用户重 ...

  6. SIFT特征原理简析(HELU版)

    SIFT(Scale-Invariant Feature Transform)是一种具有尺度不变性和光照不变性的特征描述子,也同时是一套特征提取的理论,首次由D. G. Lowe于2004年以< ...

  7. 基于IdentityServer4的OIDC实现单点登录(SSO)原理简析

    写着前面 IdentityServer4的学习断断续续,兜兜转转,走了不少弯路,也花了不少时间.可能是因为没有阅读源码,也没有特别系统的学习资料,相关文章很多园子里的大佬都有涉及,有系列文章,比如: ...

  8. 【超精简JS模版库/前端模板库】原理简析 和 XSS防范

    使用jsp.php.asp或者后来的struts等等的朋友,不一定知道什么是模版,但一定很清楚这样的开发方式: <div class="m-carousel"> < ...

  9. ARP攻击原理简析及防御措施

    0x1  简介 网络欺骗攻击作为一种非常专业化的攻击手段,给网络安全管理者,带来严峻的考验.网络安全的战场已经从互联网蔓延到用户内部的网络, 特别是局域网.目前利用ARP欺骗的木马病毒在局域网中广泛传 ...

随机推荐

  1. NPOI写Excel,Microsoft.Office.Interop.excel.dll 转换Excel为PDF

    首先要引用NPOI动态库和Microsoft.Office.Interop.excel.dll (Microsoft.Office.Interop.excel.dll 下载链接 ,下载以后解压文件,把 ...

  2. 【转载】 Eclipse注释模板设置详解

     Eclipse注释模板设置详解 网站推荐: 金丝燕网(主要内容是 Java 相关) 木秀林网(主要内容是消息队列)

  3. Confluence 6 新安装配置数据库字符集编码

    Confluence 和你的数据库必须配置使用相同的字符集. Confluence 使用 UTF-8 字符集编码,所以你的数据库也必须配置为使用 UTF-8 (或者与 UTF-8 相同的编码,例如在 ...

  4. Confluence 6 服务器的许可证信息

    Confluence 6 服务器的许可证信息. https://www.cwiki.us/display/CONFLUENCEWIKI/Managing+your+Confluence+License

  5. laravel 视图

    在实际开发中,除了 API 路由返回指定格式数据对象外,大部分 Web 路由返回的都是视图,以便实现更加复杂的页面交互,我们在前面已经看到过了视图的定义方式: return view('以.分隔的视图 ...

  6. PDF文件如何标注,怎么使用PDF标注工具

    我们在使用文件的时候需要给文件的部分添加标注,能够更加直观的了解文件,但是有很多小伙伴们对于PDF文件怎么添加标注都不知道,也不知道PDF标注工具要怎么使用,那么下面就跟大家分享一下怎么使用PDF标注 ...

  7. application program Can't Start

    一.电脑插U盘中毒之后感染,出现无法启动,但是风扇工作,先拔掉电源,卸掉电池之后重新安装,重启电脑,之后发现电脑桌面上的程序无法启动,360webShield也无法启动,可能是电脑中毒后的假死机现象. ...

  8. bzoj3276磁力 两种要求下的最大值:分块or线段树+拓扑

    进阶指南上的做法是分块的.. 但是线段树搞起来也挺快,将磁石按照距离排序,建立线段树,结点维护区间质量最小值的下标 进行拓扑,每次在可行的范围内在线段树中找到质量最小的下标取出,取出后再将线段树对应的 ...

  9. Django Web开发基础环境配置流程

    创建虚拟环境 mkvirtualenv django_py3_1.11 -p python3 注意需要联网 安装Django 使用django 1.11.11版本,注意需要联网 pip install ...

  10. ReactNative——页面跳转

    效果图: 进入工作目录,运行 react-native init NavigatorProject 创建项目NavigatorProject import React, { Component } f ...