JavaScript的几种继承方式
看《JavaScript高级程序设计》做的一些笔记
ECMAScript只支持实现继承,不支持接口继承(因为函数没有签名)
原型链(实现继承的主要方法):
function SuperType(){
this.property = true;
}
SuperType.prototype.getSuperValue = function(){
return this.property;
};
function SubType(){
this.subproperty = false;
}
//继承SuperType
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function(){
return this.subproperty;
};
var instance = new SubType();
通过原型链实现继承时不能使用对象字面量创建原型方法,否则会重写原型链
例如:
SubType.prototype = new SuperType(); //定义SubType的原型方法
SubType.prototype = { //这样定义会使上面那行代码无效 };
所有函数的默认原型都是Object的实例,因此SuperType.prototype中的[[Prototype]]会指向Object.Prototype
问题:
原型变成另一个类型的实例,原来的实例属性就变成原型属性了,因此包含引用类型值的属性会被所有SubType实例共享(例如数组)
借用构造函数:
在子类型的构造函数中使用call()或apply()调用超类型的构造函数
function SuperType(){
this.colors = [];
}
function SubType(){
//继承SuperType
SuperType.call(this);
}
可以在子类型构造函数中向超类型构造函数传递参数
问题:
方法都在构造函数中定义,函数无法复用(类似构造函数模式);在超类型原型中定义的方法对子类型不可见
组合继承(常用继承模式):
将原型链和借用构造函数组合到一块(类似组合使用构造函数模式和原型模式)
用原型链实现对原型属性和方法的继承,用借用构造函数实现对实例属性的继承
function SuperType(name){
this.name;
this.colors = [];
}
SuperType.prototype.sayName = function(){};
function SubType(name, age){
//继承属性
SuperType.call(this, name);
this.age = age;
}
//继承方法
SubType.prototype = new SuperType();
SubType.prototype.sayAge = function(){};
var instance = new SubType('myName', 66);
问题:
无论什么情况下都会调用两次超类型构造函数
同时,父类构造函数中的属性会被继承到子类的原型上
原型式继承:
基于已有的对象创建新对象,同时还不必因此创建自定义类型
function object(o){
function F(){}
F.prototype = o;
return new F();
}
var person = {
name:'myName',
friends:[]
};
var anotherPerson = object(person);
anotherPerson.name = 'anotherName';
ECMAScript5通过Object.create()规范原型式继承
问题:
与使用原型模式一样,包含引用类型的值会共享
寄生式继承:
将继承过程封装成函数,并增强对象
function createAnother(original){
var clone = object(original);
clone.sayHi = function(){};
return clone;
}
var person = {};
var anotherPerson = createAnother(person);
anotherPerson.sayHi();
问题:
不能做到函数复用,降低效率,与构造函数模式类似
寄生组合式继承:
使用寄生式继承来继承超类型的原型,再将结果指定给子类型的原型
function inheritPrototype(subType, superType){ //参数为两个类型的构造函数
var prototype = object(superType.prototype);
prototype.constructor = subType; //为创建的副本添加因重写原型而失去的constructor属性
subType.prototype = prototype;
}
function SuperType(name){
this.name = name;
this.colors = [];
}
SuperType.prototype.sayName = function(){};
function SubType(name, age){
SuperType.call(this, name);
this.age = age;
}
inheritPrototype(SubType, SuperType);
SubType.prototype.sayAge = function(){};
只调用了一次SuperType的构造函数,并且避免了在SubType.prototype上面创建不必要的、多余的属性,同时保持原型链不变
参考:《JavaScript高级程序设计》(第3版)
JavaScript的几种继承方式的更多相关文章
- JavaScript的3种继承方式
JavaScript的继承方式有多种,这里列举3种,分别是原型继承.类继承以及混合继承. 1.原型继承 优点:既继承了父类的模板,又继承了父类的原型对象: 缺点:不是子类实例传参,而是需要通过父类实例 ...
- Javascript的四种继承方式
在Javascript中,所有开发者定义的类都可以作为基类,但出于安全性考虑,本地类和宿主类不能作为基类,这样可以防止公用访问编译过的浏览器级的代码,因为这些代码可以被用于恶意攻击. 选定基类后,就可 ...
- 都0202年了,你还不知道javascript有几种继承方式?
前言 当面试官问你:你了解js哪些继承方式?es6的class继承是如何实现的?你心中有很清晰的答案吗?如果没有的话,可以通过阅读本文,帮助你更深刻地理解js的所有继承方式. js ...
- JavaScript之四种继承方式讲解
在Javascript中,所有开发者定义的类都可以作为基类,但出于安全性考虑,本地类和宿主类不能作为基类,这样可以防止公用访问编译过的浏览器级的代码,因为这些代码可以被用于恶意攻击. 选定基类后,就可 ...
- JavaScript几种继承方式
我们先构建一个Person的构造函数 function Person(name) { this.name=name; } Person.prototype.sayHi=function () { co ...
- 重新理解JS的6种继承方式
写在前面 一直不喜欢JS的OOP,在学习阶段好像也用不到,总觉得JS的OOP不伦不类的,可能是因为先接触了Java,所以对JS的OO部分有些抵触. 偏见归偏见,既然面试官问到了JS的OOP,那么说明这 ...
- JavaScript的7种继承模式
<JavaScript模式>一书中,对于JavaScript的几种继承模式讲解得很清楚,给我提供了很大帮助.总结一下,有如下7种模式. 继承模式1--设置原型(默认模式) 实现方式: // ...
- JavaScript 常见的六种继承方式
JavaScript 常见的六种继承方式 前言 面向对象编程很重要的一个方面,就是对象的继承.A 对象通过继承 B 对象,就能直接拥有 B 对象的所有属性和方法.这对于代码的复用是非常有用的. 大部分 ...
- js的6种继承方式
重新理解js的6种继承方式 注:本文引用于http://www.cnblogs.com/ayqy/p/4471638.html 重点看第三点 组合继承(最常用) 写在前面 一直不喜欢JS的OOP,在学 ...
随机推荐
- Vue#条件渲染
根据不同的条件,响应不同的事件. https://jsfiddle.net/miloer/zed5p1r3/ 可以用template来包装元素,当然浏览器的最终渲染结果不会包含它.我觉得主要用它来自定 ...
- I/O复用模型之select学习
linux下的I/O模型可以分为5种: 1.阻塞式I/O模型 2.非阻塞式I/O模型 3.I/O复用模型 4.信号驱动I/O模型 5.异步I/O模型 简单解释: 阻塞和非阻塞:就是说需要做一件事的时候 ...
- javase基础笔记4——异常/单例和类集框架
继承 extends final关键 多态 是在继承的基础上 接口 interface 异常 exception 包的访问可控制权限 private default protect public 异常 ...
- opengl纹理映射总结
大概步骤: 1.创建纹理对象,并为他指定一个纹理. 2.确定纹理如何应用到每个像素上. 3.启用纹理贴图 4.绘制场景,提供纹理和几何坐标 过滤:由于我们提供的纹理图像很少能和最终的屏幕坐标形成对应, ...
- Windows服务定时执行任务
1.创建多线程类 /// <summary> /// 多线程 /// </summary> public abstract class MuliThread<T> ...
- this和super
1.this * 每个类的每个非静态方法(没有被static修饰)都会隐含一个this引用名称,它指向调用这个方法的对象. * 当在方法中使用本类的属性时,都会隐含地使用this名称,当然也可以明确指 ...
- 大端模式 VS 小端模式
简单点说,就是字节的存储顺序,如果数据都是单字节的,那怎么存储无所谓了,但是对于多字节数据,比如int,double等,就要考虑存储的顺序了.注意字节序是硬件层面的东西,对于软件来说通常是透明的.再说 ...
- python装饰器--@property
@property 考察 Student 类: class Student(object): def __init__(self, name, score): self.name = name sel ...
- Angular.js 以及个人学习网站
Angular.js 教程 http://www.360doc.com/content/14/0414/15/14416931_368816305.shtml web前端学习: 慕课网:http:/ ...
- time元素
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...