js的几种继承方式
1、原型链方式
function Super(){
this.val = 1;
this.arr = [1];
}
function Sub(){
// ...
}
Sub.prototype = new Super(); // 核心
var sub1 = new Sub();
var sub2 = new Sub();
sub1.val = 2;
sub1.arr.push(2);
alert(sub1.val); //
alert(sub2.val); //
alert(sub1.arr); // 1, 2
alert(sub2.arr); // 1, 2
拿父类实例来充当子类原型对象
优点:
- 简单,易于实现
缺点:
修改sub1.arr后sub2.arr也变了,因为来自原型对象的引用属性是所有实例共享的。
可以这样理解:执行sub1.arr.push(2);先对sub1进行属性查找,找遍了实例属性(在本例中没有实例属性),没找到,就开始顺着原型链向上找,拿到了sub1的原型对象,一搜身,发现有arr属性。于是给arr末尾插入了2,所以sub2.arr也变了
创建子类实例时,无法向父类构造函数传参
2、借用构造函数方式
function Super(val){
this.val = val;
this.arr = [1];
this.fun = function(){
// ...
}
}
function Sub(val){
Super.call(this, val); // 核心
// ...
}
var sub1 = new Sub(1);
var sub2 = new Sub(2);
sub1.arr.push(2);
alert(sub1.val); //
alert(sub2.val); //
alert(sub1.arr); // 1, 2
alert(sub2.arr); //
alert(sub1.fun === sub2.fun); // false
借父类的构造函数来增强子类实例,等于是把父类的实例属性复制了一份给子类实例装上了(完全没有用到原型)
优点:
解决了子类实例共享父类引用属性的问题
创建子类实例时,可以向父类构造函数传参
缺点:
- 无法实现函数复用,每个子类实例都持有一个新的fun函数,太多了就会影响性能,内存爆炸。。
3、组合继承方式
function Super(){
// 只在此处声明基本属性和引用属性
this.val = 1;
this.arr = [1];
}
// 在此处声明函数
Super.prototype.fun1 = function(){};
Super.prototype.fun2 = function(){};
//Super.prototype.fun3...
function Sub(){
Super.call(this); // 核心
// ...
}
Sub.prototype = new Super(); // 核心
var sub1 = new Sub(1);
var sub2 = new Sub(2);
alert(sub1.fun === sub2.fun); // true
把实例函数都放在原型对象上,以实现函数复用。同时还要保留借用构造函数方式的优点,通过Super.call(this);继承父类的基本属性和引用属性并保留能传参的优点;通过Sub.prototype = new Super();继承父类函数,实现函数复用
优点:
- 不存在引用属性共享问题
- 可传参
- 函数可复用
缺点:
- (一点小瑕疵)子类原型上有一份多余的父类实例属性,因为父类构造函数被调用了两次,生成了两份,而子类实例上的那一份屏蔽了子类原型上的。。。又是内存浪费,比刚才情况好点,不过确实是瑕疵
4、寄生组合继承方式
function beget(obj){
var F = function(){};
F.prototype = obj;
return new F();
}
function Super(){
// 只在此处声明基本属性和引用属性
this.val = 1;
this.arr = [1];
}
// 在此处声明函数
Super.prototype.fun1 = function(){};
Super.prototype.fun2 = function(){};
//Super.prototype.fun3...
function Sub(){
Super.call(this); // 核心
// ...
}
var proto = beget(Super.prototype); // 核心
proto.constructor = Sub; // 核心
Sub.prototype = proto; // 核心
var sub = new Sub();
alert(sub.val);
alert(sub.arr);
转载:https://www.cnblogs.com/ayqy/p/4471638.html
js的几种继承方式的更多相关文章
- js的6种继承方式
重新理解js的6种继承方式 注:本文引用于http://www.cnblogs.com/ayqy/p/4471638.html 重点看第三点 组合继承(最常用) 写在前面 一直不喜欢JS的OOP,在学 ...
- 细说 js 的7种继承方式
在这之前,先搞清楚下面这个问题: function Father(){} Father.prototype.name = 'father'; Father.prototype.children = [ ...
- js的三种继承方式及其优缺点
[转] 第一种,prototype的方式: //父类 function person(){ this.hair = 'black'; this.eye = 'black'; this.skin = ' ...
- 重新理解JS的6种继承方式
写在前面 一直不喜欢JS的OOP,在学习阶段好像也用不到,总觉得JS的OOP不伦不类的,可能是因为先接触了Java,所以对JS的OO部分有些抵触. 偏见归偏见,既然面试官问到了JS的OOP,那么说明这 ...
- js的5种继承方式——前端面试
js主要有以下几种继承方式:对象冒充,call()方法,apply()方法,原型链继承以及混合方式.下面就每种方法就代码讲解具体的继承是怎么实现的. 1.继承第一种方式:对象冒充 function P ...
- js的2种继承方式详解
js中继承可以分为两种:对象冒充和原型链方式 一.对象冒充包括三种:临时属性方式.call()及apply()方式1.临时属性方式 复制代码代码如下: function Person(name){ ...
- JavaScript_几种继承方式(2017-07-04)
原型链继承 核心: 将父类的实例作为子类的原型 //父类 function SuperType() { this.property = true; } SuperType.prototype.ge ...
- js实现的几种继承方式
他山之石,可以攻玉,本人一直以谦虚的态度学他人之所长,补自己之所短,望各位老师指正! 拜谢 js几种继承方式,学习中的总结: 所谓的继承是为了继承共有的属性,减少不必要代码的书写 第一种:借用构造函数 ...
- 都0202年了,你还不知道javascript有几种继承方式?
前言 当面试官问你:你了解js哪些继承方式?es6的class继承是如何实现的?你心中有很清晰的答案吗?如果没有的话,可以通过阅读本文,帮助你更深刻地理解js的所有继承方式. js ...
随机推荐
- login-Linux必学的60个命令
1.作用 login的作用是登录系统,它的使用权限是所有用户. 2.格式 login [name][-p ][-h 主机名称] 3.主要参数 -p:通知login保持现在的环境参数. -h:用来向远程 ...
- CodeForces - 27E
https://vjudge.net/problem/CodeForces-27E 求因子个数为n的最小的数dfs枚举质因子的幂 #include <iostream> #include ...
- postgresql计算2个日期之间工作日天数的方法
select date_part( 'day', minus_weekend(begin_date,end_date)) from table1 where name in ('a', 'b', 'c ...
- SQLServer索引的四个高级特性
一Index Building Filter索引创建时过滤 二Index Include Column索引包含列 三聚集索引Cluster Index 四VIEW INDEX视图索引 SQLSer ...
- Cooki and Session
目录 Cookie Cookie的由来 什么是Cookie Cookie的原理 查看Cookie Django中操作Cookie 获取Cookie 设置Cookie 删除Cookie Session ...
- matlab-变量类型-数组-矩阵
1 变量类型 1.1基本 1.2 特殊变量 ans •i,j: complex number •Inf: 无穷大 •eps: 2.2204e-016 •NaN: not a number •pi:pa ...
- 如何 在 jQuery 中的 $.each 循环中使用 break 和 continue
jQuery中each类似于javascript的for循环 但不同于for循环的是在each里面不能使用break结束循环,也不能使用continue来结束本次循环,想要实现类似的功能就只能用ret ...
- 使用ResponseEntity进行返回json数据
在最近的项目中,与上位机进行数据传输时,上位机需要服务器的响应得知服务器是否正常运行,数据是否正常发送 在最近的调试中我使用ResponseEntity<Map<String,Object ...
- 如何做系列(1)- mybatis 如何实现分页?
第一个做法,就是直接使用我们的sql语句进行分页,也就是在mapper里面加上分页的语句就好了. <select id="" parameterType="&quo ...
- [Ceoi2011]Traffic
#2387. [Ceoi2011]Traffic Online Judge:Bzoj-2387,Luogu-4700 Label:Yy,Tarjan缩点,dfs 题目描述 格丁尼亚的中心位于Kacza ...