看《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的几种继承方式的更多相关文章

  1. JavaScript的3种继承方式

    JavaScript的继承方式有多种,这里列举3种,分别是原型继承.类继承以及混合继承. 1.原型继承 优点:既继承了父类的模板,又继承了父类的原型对象: 缺点:不是子类实例传参,而是需要通过父类实例 ...

  2. Javascript的四种继承方式

    在Javascript中,所有开发者定义的类都可以作为基类,但出于安全性考虑,本地类和宿主类不能作为基类,这样可以防止公用访问编译过的浏览器级的代码,因为这些代码可以被用于恶意攻击. 选定基类后,就可 ...

  3. 都0202年了,你还不知道javascript有几种继承方式?

    前言     当面试官问你:你了解js哪些继承方式?es6的class继承是如何实现的?你心中有很清晰的答案吗?如果没有的话,可以通过阅读本文,帮助你更深刻地理解js的所有继承方式.       js ...

  4. JavaScript之四种继承方式讲解

    在Javascript中,所有开发者定义的类都可以作为基类,但出于安全性考虑,本地类和宿主类不能作为基类,这样可以防止公用访问编译过的浏览器级的代码,因为这些代码可以被用于恶意攻击. 选定基类后,就可 ...

  5. JavaScript几种继承方式

    我们先构建一个Person的构造函数 function Person(name) { this.name=name; } Person.prototype.sayHi=function () { co ...

  6. 重新理解JS的6种继承方式

    写在前面 一直不喜欢JS的OOP,在学习阶段好像也用不到,总觉得JS的OOP不伦不类的,可能是因为先接触了Java,所以对JS的OO部分有些抵触. 偏见归偏见,既然面试官问到了JS的OOP,那么说明这 ...

  7. JavaScript的7种继承模式

    <JavaScript模式>一书中,对于JavaScript的几种继承模式讲解得很清楚,给我提供了很大帮助.总结一下,有如下7种模式. 继承模式1--设置原型(默认模式) 实现方式: // ...

  8. JavaScript 常见的六种继承方式

    JavaScript 常见的六种继承方式 前言 面向对象编程很重要的一个方面,就是对象的继承.A 对象通过继承 B 对象,就能直接拥有 B 对象的所有属性和方法.这对于代码的复用是非常有用的. 大部分 ...

  9. js的6种继承方式

    重新理解js的6种继承方式 注:本文引用于http://www.cnblogs.com/ayqy/p/4471638.html 重点看第三点 组合继承(最常用) 写在前面 一直不喜欢JS的OOP,在学 ...

随机推荐

  1. Win10 开发者模式开启

    使用注册表方式:建立一个注册表DWORD为1键值:HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock\AllowAllTrust ...

  2. 上四条只是我目前总结菜鸟们在学习FPGA时所最容易跑偏的地

    长期以来很多新入群的菜鸟们总 是在重复的问一些非常简单但是又让新手困惑不解的问题.作为管理员经常要给这些菜鸟们普及基础知识,但是非常不幸的是很多菜鸟怀着一种浮躁的心态来学习 FPGA,总是急于求成. ...

  3. win8.1/win10 UEFI + GPT 安装(测试机型:华硕S56CM)

    本教程简要介绍在UEFI 启动模式下在GPT分区表中,最简单的方法安装 Windows 10 x64 位系统.(并非傻瓜教程,安装者总要有一定的经验基础)下面先简单介绍一下UEFI和GTP. UEFI ...

  4. Printf()输出格式控制(转)

    int printf(const char *format,[argument]); format 参数输出的格式,定义格式为: %[flags][width][.perc] [F|N|h|l]typ ...

  5. 编译原理实习(应用预测分析法LL(1)实现语法分析)

    #include<iostream> #include<fstream> #include<iomanip> #include<cstdio> #inc ...

  6. Vs2012调试本地windows服务

    背景: 在我的工作经历中,我用到了一个我们以前学习中没有接触过的老东西-服务.之所说以前没有接触过,是因为自己没有系统的研究过这东西:之所以又说它是老东西,是因为我们其实早就知道他的存在,经常用它去干 ...

  7. 【MyEcplise hibernate tools】hibernate tools的使用以及错误

    1.点击Myecplise右上角 2.点击进入后,在这个区域右键 New 一个新的connection 3.以mySql连接为例子,在这里展示一下,下面这几项必须都要按照要求完全一致,除了架包所在的本 ...

  8. C#开发微信公众平台-就这么简单(附Demo)(转)

    原文:http://www.cnblogs.com/xishuai/p/3625859.html 写在前面 阅读目录: 服务号和订阅号 URL配置 创建菜单 查询.删除菜单 接受消息 发送消息(图文. ...

  9. 配置.net连接数据库的配置文件

    今天调试一个学生信息管理系统时,启动系统之后,登录时老是报错说实例有问题,拿着报错信息去找方法也没遇到能解决问题的,最后怀疑是数据库配置和配置文件不匹配, 发现自己的数据库里并没有SQLEXPRESS ...

  10. 分享Kali Linux 2016.2第49周虚拟机

    分享Kali Linux 2016.2第49周虚拟机该虚拟机使用Kali Linux 2016.2第49周的64位镜像安装而成.基本配置如下:(1)该系统默认设置单CPU双核,内存为2GB,硬盘为50 ...