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 ...
随机推荐
- Linux中的任务调度
1.crond,linux中的任务调度器 crond的概念和crontab是不可分割的.crontab是一个命令,常见于Unix和类Unix的操作系统之中,用于设置周期性被执行的指令.该命令从标准输入 ...
- 架构师养成记--24.linux常用命令
一.Linux 文件 根据上文Linux 文件说明1.文件的rwx d开头表示文件夹, -开头的表示文件, l开头表示链接文件 r:read,w:write,x:execute ...
- 2016级算法期末上机-I.难题·ModricWang's Fight with DDLs III
1126 ModricWang's Fight with DDLs III 思路 由于题目中已经说明了时间经过了正无穷,因此初始位置是不重要的,并且每条边.每个点的地位是均等的.因此到达每个点的概率就 ...
- java中mongo的条件查询
@Override public Page<ProductInfo> findAll(Pageable pageable, ProductInfo productInfo) { //创建一 ...
- 28.earch in Rotated Sorted Array(排序旋转数组中查找)
Level: Medium 题目描述: Suppose an array sorted in ascending order is rotated at some pivot unknown to ...
- VUE 项目dependency was not found: * !!vue-style-loader!css-loader? 解决方案
用npm run dev 运行vue项目时,出现以下错误: ERROR Failed to compile with errors :: This dependency was not found: ...
- driver failed programming external connectivity on endpoint wordpress
docker run 镜像的时候报错: [root@docker ~]# docker run -itd --name wordpress -p 88:80 wordpress:v1b77482f80 ...
- Visual Studio 2019 Key
Visual Studio 2019 Enterprise:BF8Y8-GN2QH-T84XB-QVY3B-RC4DF Visual Studio 2019 Professional:NYWVH-HT ...
- java翻译到mono C#实现系列(4) 利用CountDownTimer类实现倒计时功能 mono版
群里的朋友问利用CountDownTimer类实现倒计时功能怎么实现,我就百度了,参考http://blog.csdn.net/qq344429461/article/details/7521361写 ...
- ADO.NET中DbConnection.GetSchema方法的使用总结
此方法获取数据库的结构,所以可以用它获取数据库中所有的表 先上代码 string connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;U ...