《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上就不会有不必要的属性了。

时间: 2024-08-07 19:00:02

《JavaScript高级程序设计》第6章补充 继承的相关文章

javascript高级程序设计 第十三章--事件

javascript高级程序设计 第十三章--事件js与HTML的交互就是通过事件实现的,事件就是文档或浏览器窗口中发生的一些特定的交互瞬间. 事件流:事件流描述的是从页面中接收事件的顺序,IE的是事件冒泡流,Netscape的是事件捕获流,这个两个是完全相反的事件流概念. 事件冒泡:由最具体的元素接收,然后逐级向上传播到更高级的节点,即事件沿DOM树向上传播,直到document对象. 事件捕获:不大具体的节点应该更早接收到事件,相当于沿DOM节点树向下级传播直到事件的实际目标,在浏览器中,是

javascript高级程序设计 第十一章--DOM扩展

javascript高级程序设计 第十一章--DOM扩展DOM最主要的扩展就是选择符API.HTML5和Element Traversal Selectors API:定义了两个方法 querySelector() 和 querySelectorAll(),能够基于CSS选择符从DOM中取得元素.querySelector()方法接收一个CSS选择符,返回该模式匹配的第一个元素,querySelectorAll()接收的参数一样,但是返回NodeList实例: matchesSelector()

Javascript高级程序设计——第三章:基本概念

javascript高级程序设计——第三章:基本概念 一.语法 EMCA-262通过叫做ECMAScript的“伪语言”为我们描述了javascript实现的基本概念 javascript借鉴了C的语法,区分大小写,标示符以字母.下划线.或美元符号($)开头,注释可以用 // 或者/* */ 严格模式: ECMAScript 5引入了严格模式,在严格模式下不确定的行为将得到处理,通过在顶部添加 “use strict”来启用严格模式: function fuc(){ "use strict&qu

《JavaScript高级程序设计第五章--引用类型》之Object对象和array对象

这一章主要就是介绍各种内置对象的用法,认识其经常用到的属性和方法. 5.1Object类型 创建objec的方式,一种是new Object(),一种是对象字面量(简化创建包含大量属性的对象的过程) var person = { name = "Nicholas"; age = 27 };//最后一个属性不必添加逗号,ie7等会导致错误 //在使用对象字面量语法时,属性名也可以使用字符串.这里的数值属性会自动转字符串. var person = { "name" :

javascript高级程序设计 1 ~ 3 章 部分知识点总结

第一章 javascript简介 javascript的简介,有关js的一些历史问题. js初期在不同的浏览器存在很大的兼容问题,但是慢慢的大家都在向标准靠拢,兼容问题已经好很多了. 我们通常会听到ECMAScript,它跟javascript是什么关系呢? JS = ES + BOM(浏览器对象模型) + DOM(文档对象模型)  ES就是对javascript的类型,值,对象,属性,函数以及程序句法和语义,DOM就是ES运行在浏览器环境的时候,浏览器为其提供的扩展以实现更多更具体的功能(we

《JAVASCRIPT高级程序设计》第一章

在使用调制解调器的时代,频繁的表单验证对客户端来说是一个很大的负担,javascript,作为一种专门进行表单验证的客户端脚本语言诞生了.到今天,javascript早已超越了当初设定的角色.Javascript由以下三部分组成: 核心(ECMAScript) 文档对象模型(DOM) 浏览器对象模式(BOM) 一.ECMAScript ECMAScript是对Javascript这门语言的描述,它规定了这门语言的这些组成部分:语法.类型.语句.关键字.保留字.操作符.对象.Web浏览器是ECMA

JavaScript高级程序设计第20章JSON 笔记 (学习笔记)

第二十章 JSON 1.Json 可以表示三种类型的值: 1.简单值: 表示数值:5  表示字符串:“hello wrold”注表示字符串时必须使用双引号 2.对象: {“name”:“mi”,”age”:24}与JavaScript对象有两处不同一是没有声明变量 二是没有末尾的分号json对象中属性必须带引号,对象里的值可以嵌套对象. 3.数组 Json数组表示:[25,”hi”,true]和json对象一样json里也没有分号和变量 2.json对象 1.Stringify()方法用于把ja

JavaScript高级程序设计第14章表单脚本 (学习笔记)

第十四章 表单脚本 1.阻止默认表单提交 1.提交表单数据 1.使用type=submit提交按钮 2.使用submit():方法 注意:当用户点击提交按钮时,会触发submit事件,从而在这里我们有机会验证数据并决定要不要提交表单 1.preventnDefault(event):可以用在表单数据无效时不发给服务器,对于动态绑定的onclick 事件. 2.Submit()方法也可以提交表单,但是不会触发submit事件,所以在使用时须先验证表单数据, 如:<%response.write(t

《JAVASCRIPT高级程序设计》第二章

把javascript应用在网页中,需要涉及web的核心语言-html:如何让javascript既能与html共存,又不影响页面的显示效果,经过长时间的讨论.试错,最终的决定是为web增加统一的脚本支持.向html插入javascript最主要的做法,是借助<script>标签. 如果不指定type,type默认是“text/javascript" 1)在页面嵌入JS代码 1 <script type="text/javascript"> 2 fun

JavaScript高级程序设计:第二章

在HTML中使用JavaScript 1.<script>元素:向HTML页面中插入JavaScript的主要方法就是使用<scritp>元素.HTML4.01为<script>定义了下列6个属性. (1)async:可选.表示立即下载脚本,但不妨碍页面中的其他操作,比如下载其他资源或等待加载其他脚本.只对外部脚本文件有效. (2)charset:可选.表示通过src属性指定的代码的字符集.由于大多数浏览器会忽略它的值,因此这个属性很少有人用. (3)defer:可选.