JS深拷贝继承
所谓深拷贝,就是子对象不紧继承父对象的非引用属性,还能继承父对象的引用属性(Object,Array),当子对象对继承的引用类型属性做修改时,父对象的引用类型不会被修改。
我们先写个浅拷贝的封装函数:
function extendCopy(parent){
var child={};
for(var i in parent){
child[i]=parent[i];
}
child.uber=parent;
return child;
}
接下来写个深拷贝的封装函数:
function deepCopy(p,c){
var c=c||{};
for(var i in p){
if(typeof p[i]==="object"){
c[i]=(p[i].constructor===Array)? [] : {};
deepCopy(p[i],c[i]);
}else{
c[i]=p[i];
}
}
return c;
}
分析两个函数有何不同,extendCopy方法是将父对象的属性和方法逐个的拷贝给子对象,当遇到引用类型的属性时,比如数组,那么若对子对象拷贝而来的数组进行重写时,父对象对应的数组也会随之改变,因为他们指向的是同一地址。
而deepCopy方法:
举个栗子:
var parent={
score:[1,2,3,4];
}
var child=deepCopy(parent);
执行deepCopy函数后,当执行到
if(typeof parent[score]==='object')时,
child[score]=[];
再执行deepCopy(parent[score],child[score]);
此时typeof p[i]就不是'object'类型了,而是number类型,
所以
child[score][1]=parent[score][1]=1;
child[score][2]=parent[score][2]=2;
child[score][3]=parent[score][3]=3;
child[score][4]=parent[score][4]=4;
在return child[score];
这样就完成了深拷贝,child[score]和parent[score]不是指向同一个地址了。但此时两者值相同,只是地址不同,若再对child[score]做修改,parent[score]不会有任何变化。
我们来试验一下:
var Shape={
color:"blue",
name:"shape",
size:[1,2,3,4],
getName:function(){
return this.name;
}
} var circle=deepCopy(Shape);
var tran=extendCopy(Shape);
circle.size.push(5,6);
console.log(circle.size); //[1,2,3,4,5,6]
console.log(Shape.size);//[1,2,3,4] 深拷贝父对象值没有变化
tran.size.push(5,6,7,8);
console.log(circle.size); //[1,2,3,4,5,6]
console.log(tran.size);//[1,2,3,4,5,6,7,8]
console.log(Shape.size); //[1,2,3,4,5,6,7,8] 浅拷贝随着tran.size的改变,Shape.size也会随之改变,
上述demo很好的验证了浅拷贝和深拷贝的区别
JS深拷贝继承的更多相关文章
- JS对象继承篇
JS对象继承篇 ECMAScript只支持实现继承,而且其实现继承主要是依靠原型链来实现的 原型链 其基本思路是利用原型让一个引用类型继承另一个引用类型的属性和方法 function Person() ...
- js实现继承的5种方式 (笔记)
js实现继承的5种方式 以下 均为 ES5 的写法: js是门灵活的语言,实现一种功能往往有多种做法,ECMAScript没有明确的继承机制,而是通过模仿实现的,根据js语言的本身的特性,js实现继承 ...
- js实现继承的方式总结
js实现继承的5种方式 以下 均为 ES5 的写法: js是门灵活的语言,实现一种功能往往有多种做法,ECMAScript没有明确的继承机制,而是通过模仿实现的,根据js语言的本身的特性,js实现继承 ...
- 【09-23】js原型继承学习笔记
js原型继承学习笔记 function funcA(){ this.a="prototype a"; } var b=new funcA(); b.a="object a ...
- js实现继承的两种方式
这是面试时面试官会经常问到问题: js的继承方式大致可分为两种:对象冒充和原型方式: 一.先说对象冒充,又可分为3种:临时属性方式.call().apply(): 1.临时属性方式: 当构造对象son ...
- js实现继承
js是门灵活的语言,实现一种功能往往有多种做法,ECMAScript没有明确的继承机制,而是通过模仿实现的,根据js语言的本身的特性,js实现继承有以下通用的几种方式1.使用对象冒充实现继承(该种实现 ...
- 浅谈JS的继承
JS继承 继承是OO语言中最为人津津乐道的概念,许多OO语言都支持两种方式的继承:接口继承:实现继承. 接口继承:只继承方法签名. 实现继承:继承实际的方法. 由于ES里函数没有签名,所以在ES里面无 ...
- JS类继承常用方式发展史
JS类继承常用方式发展史 涉及知识点 构造函数方式继承 1-继承单个对象 1.1 多步走初始版 1.2 多步走优化版 1.3 Object.create()方式 2-继承多个对象 2.1 遍历 Obj ...
- js 深拷贝和浅拷贝
js 深拷贝和浅拷贝 先举一下项目中遇到的两个例子: 例子1: var json = $.parseJSON(data.data);//data.data是接口返回的值var a = json.cha ...
随机推荐
- 浅谈Android选项卡(四)
前面几篇介绍的选项的用法,基本上使用TabActivity.ViewPager.已经基本上满足开发需求了.但是这里再介绍一种小技巧,在有的时候,感觉使用前面的ViewPager和Fragment时候, ...
- Dota2APP--第一天
从今天开始,下定决心自己独立开发一个有关于Dota2的APP,因为非常喜欢这个游戏恰好自己又是做iOS移动开发的所以萌生了这个想法.希望可以坚持下去,有喜欢dota2的朋友也可以提点建议. 一.项目的 ...
- 初识gulp
之前一段时间学习使用了gulp自动化构建工具,并在现在使用的项目上部署使用,同时在这做个笔记进行小结,以便加深记忆,如有理解错误的地方请不吝赐教 gulp 的解释我就不多说了 这里引用官网的一句话 ...
- ToolkitScriptManager vs. ScriptManager 关于“只能向页面中添加 ScriptManager 的一个实例”讨论
在使用ASP.NET设计AJAX功能网页时,需要首先声明ToolkitScriptManager或者ScriptManager控件,这些全局的脚本核心控制,然后才能使用众多的AJAX控件.如果没有创建 ...
- Eclipse/MyEclipse按任何键,都可以提示?(最强帮手)
说明: 一般在Eclipse ,MyEclipse代码里面,打个foreach,switch等这些,是无法得到代码提示的(不信自己试试),其他的就更不用说了,而在Microsoft Visual St ...
- Examples of GoF Design Patterns--摘录
http://stackoverflow.com/questions/1673841/examples-of-gof-design-patterns You can find an overview ...
- Elastic Kibana - Install as windows service
#1 通过windows sc 服务命令安装 sc create "Kibana661" binPath= "{path}\kibana.bat" depend ...
- Tomcat源码分析——请求原理分析(上)
前言 谈起Tomcat的诞生,最早可以追溯到1995年.近20年来,Tomcat始终是使用最广泛的Web服务器,由于其使用Java语言开发,所以广为Java程序员所熟悉.很多人早期的J2EE项目,由程 ...
- 从父子组件的mounted钩子的同步执行与页面的异步渲染看nextTick的用法
最近复习vue的时候遇到了一个很奇怪的问题,我们直接从实例中看: <div id="app"> <child ref="child">& ...
- IOS Core Image之一
项目中要实现高斯模糊的效果,今天看了下Core Image这块的内容, 主要包括CIImage.CIFilter.CIContext.CIDetector(检测).CIFeature(特征)等类. 今 ...