《JavaScript高级程序设计》第6章补充 继承
基于原型链继承
将父类的实例赋给子类的prototype来实现继承。
原理:父类的实例有父类所有的实例属性和原型方法,将它赋给子类的prototype后,子类的创建的实例就有会__proto__属性指向这个prototype(它拥有父类所有的实例属性和原型方法),实现继承。
function SuperType() {
this.property = true;
}
SuperType.prototype.getSuperValue = function() {
return this.property;
}
function SubType() {
this.subproperty = false;
}
// 关键一步
SubType.prototype = new SuperType();
// 定义自己的方法,注意要放在父类实例赋值之后
SubType.prototype.getSubValue = function () {
return this.subproperty;
}

原型链继承的问题:本来在父类中的实例属性(如上图property),到了子类中变成了原型属性,这样违反了每个实例有自己独有的实例属性的原则(如果是个数组的话又会一改就全部实例都改了)。
借调用父类的构造函数继承
在子类的构造函数中调用父类的构造函数,同时用call把this绑定在对应的实例上(即目前的this)。
function SuperType() {
// SubType的实例(instance1、instance2)来到这里之后,color变成了他们的属性(实例属性)
this.color = ["red", "blue", "green"];
}
// 这里的this是SubType的实例(instance1、instance2),然后借调用父类的构造函数,并把this传进去。
function SubType() {
SuperType.call(this);
}
var instance1 = new SubType();
instance1.color.push("black");
console.log(instance1.color);
var instance2 = new SubType();
console.log(instance2.color);
借调用构造函数的方式的问题也很明显:所有方法都不能在原型上定义了,本来方法应该要定义在原型中,达到重用的目的。
组合继承
原型链实现对原型属性和方法的继承,借调用构造函数实现对实例属性的继承。
function SuperType(name) {
this.name = name;
this.color = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function () {
console.log(this.name);
}
function SubType(name, age) {
// 继承父类属性
SuperType.call(this, name);
// 添加子类自己的实例属性
this.age = age;
}
// 继承父类方法(原型方法)
SubType.prototype = new SuperType();
// 虽然这样color还是变成了SubType的原型属性,但是不要紧,借调用的时候实例会被重新添加一次实例属性color
// 这个实例属性color就会屏蔽掉原型属性color
SubType.prototype.constructor = SubType;
// 添加子类自己的原型方法
SubType.prototype.sayAge = function () {
console.log(this.age);
}
var instance1 = new SubType("Nicholas", 29);
instance1.color.push("black");
console.log(instance1.color); // ["red", "blue", "green", "black"]
var instance2 = new SuperType("Greg", 27);
console.log(instance2.color); // ["red", "blue", "green"]
这是最常用的继承模式。
寄生组合式继承
由于子类的prototype并不想要父类的实例属性,我们只想要子类的prototype的__proto__可以指向父类的prototype而已。
所以用 SubType.prototype = new SuperType(); 这种方式实际上不是很完美
// 这个函数的作用简单来说就是输入一个对象,返回一个__proto__指向它的对象
function object(o) {
function F() {}
F.prototype = o;
return new F();
} // 这个函数的作用就是让子类的prototype的__proto__可以指向父类的prototype
function inheritPrototype(subType, superType) {
var prototype = object(superType.prototype);
prototype.constructor = subType;
subType.prototype = prototype;
} function SuperType() {
// 父类的属性
this.name = name;
this.color = ["red", "blue", "green"];
}
// 父类的方法
SuperType.prototype.sayName = function () {
console.log(this.name);
} function SubType(name, age) {
// 继承父类属性
SuperType.call(this, name);
// 子类自己的属性
this.age = age;
}
// 继承父类方法(对子类的prototype动手脚),但不是像以前那样简单地 SubType.prototype = new SuperType();
inheritPrototype(SubType, SuperType);
// 子类自己的方法
SubType.prototype.sayAge = function () {
console.log(this.age);
}
这样SubType.prototype上就不会有不必要的属性了。
《JavaScript高级程序设计》第6章补充 继承的更多相关文章
- 《JavaScript高级程序设计》——第二章在HTML使用JavaScript
这章讲的是JavaScript在HTML中的使用,也就是<script>元素的属性.书中详细讲了async.defer.src和type四个<script>的属性. 下面是对第 ...
- JavaScript 高级程序设计 第5章引用类型 笔记
第五章 引用类型 一.object类型 1.创建方法: 1.使用new 操作符创建 var person=new object() Person.name=”Nicholasa” Porson.age ...
- 《JavaScript 高级程序设计》第一章:简介
JavaScript 历史 JavaScript的诞生的主要是当时的 netspace 公司谋求为自己的浏览器 Navigator 添加一种脚本语言,以便在本地客户端进行一些行为操作,而这一功能的需求 ...
- JavaScript高级程序设计第20章JSON 笔记 (学习笔记)
第二十章 JSON 1.Json 可以表示三种类型的值: 1.简单值: 表示数值:5 表示字符串:“hello wrold”注表示字符串时必须使用双引号 2.对象: {“name”:“mi”,”ag ...
- JavaScript高级程序设计第14章表单脚本 (学习笔记)
第十四章 表单脚本 1.阻止默认表单提交 1.提交表单数据 1.使用type=submit提交按钮 2.使用submit():方法 注意:当用户点击提交按钮时,会触发submit事件,从而在这里我们有 ...
- 《JAVASCRIPT高级程序设计》第一章
在使用调制解调器的时代,频繁的表单验证对客户端来说是一个很大的负担,javascript,作为一种专门进行表单验证的客户端脚本语言诞生了.到今天,javascript早已超越了当初设定的角色.Java ...
- 《JavaScript高级程序设计》——第一章JavaScript简介
第一章主要讲了JavaScript的诞生和发展.刚刚接触JavaScript的我,似乎对这些内容并不感兴趣,快速看了一遍就开始去看第二章了. 看完第一章,收获也就是了解到JavaScript由ECMA ...
- javascript高级程序设计第5章,引用类型
object类型: 创建object实列的方式有两种,一种是new()方法,一种是对象字面量表示法: 第一种法方: var obj = new object(); obj.name = 'name' ...
- javascript高级程序设计第四章 变量、作用域和内存问题
变量包含两种,,基本类型和引用类型 基本类型是指一些简单的字段: 引用类型是☞由多个值构成的对象 引用类型的值是保存在内存中的对象,在javascript中是不允许直接访问内存中的位置; 函数的参数 ...
- 读javascript高级程序设计06-面向对象之继承
原型链是实现继承的主要方法,通过原型能让一个引用类型继承另一个引用类型. 1.原型链实现继承 function SuperType(){ this.superprop=1; } SuperType.p ...
随机推荐
- 巨蟒python全栈开发-第9天 初识函数
一.今日主要内容总览(重点) 1.什么是函数? f(x)=x+1 y=x+1 函数是对功能或者动作的封装2.函数的语法和定义 def 函数名(): 函数体 调用:函数名()3.关于函数的返回值 ret ...
- ios cocos2d 使用 sneakyInput 插件
昨晚看了篇使用sneakyInput插件实现模拟手柄的代码,不过我加上后出现了很多问题.最后只看如何实现,没有自己动手去操作.今天终于吧问题都解决了.记录下来.也供别人参考. 首先要先加入libz.d ...
- quartz集群 定时任务 改成可配置
前面的博文中提到的quartz集群方式会有以下缺点: 1.假设配置了3个定时任务,job1,job2,job3,这时数据库里会有3条job相关的记录,如果下次上线要停掉一个定时任务job1,那即使定时 ...
- 解决 pip 安装opendr包 卡住的问题
使用豆瓣的源(已经确认过了该源中有opendr包),pip安装opendr,结果卡在了下载完成的位置,什么提示也没有.(如下图) 既然安装包已经下载下来了又安装不上,则应该是安装代码中有什么问题,只不 ...
- 《深入理解Linux内核》阅读笔记 --- 第四章 中断和异常
1.中断的作用:中断信号提供了一种方式,使处理器转而去运行正常控制流之外的代码.当一个中断信号到达时,CPU必须停止它当前所做的事,并切换到一个新的活动.为了做到这一点,就要在内核态堆栈保存程序计数器 ...
- LeetCode:二叉搜索树中的搜索【700】
LeetCode:二叉搜索树中的搜索[700] 题目描述 给定二叉搜索树(BST)的根节点和一个值. 你需要在BST中找到节点值等于给定值的节点. 返回以该节点为根的子树. 如果节点不存在,则返回 N ...
- springmvc 自定义拦截器
<mvc:interceptors> <!-- 配置自定义的拦截器 --> <bean class="com.atguigu.springmvc.interce ...
- 【转】PCA与Whitening
PCA: PCA的具有2个功能,一是维数约简(可以加快算法的训练速度,减小内存消耗等),一是数据的可视化. PCA并不是线性回归,因为线性回归是保证得到的函数是y值方面误差最小,而PCA是保证得到的函 ...
- Sublime Text Shortcuts
Keyboard Shortcuts - Windows/Linux Warning This topic is a draft and may contain wrong information. ...
- Oracle数据安全(四)j角色管理
一.角色管理的概述 1.角色的概念 为了简化数据库权限的管理,在Oracle数据库中引入了角色的概念.所谓的角色就是一系列相关权限的集合. 2.角色的特点 在数据库中,角色的名称必须是唯一的,不能与用 ...