许多OO语言都支持两种继承方式,接口继承和实现继承。接口继承只继承方法签名,而实现继承则继承实际的方法。由于在ECMAScript中,函数没有签名,无法实现接口继承,只支持实现继承,而且其实现继承主要是通过原型链来实现的。

一. 原型链模式

利用原型让引用类型继承另一个引用类型的属性和方法。

原型、构造函数和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针, 而实例包含一个指向原型对象的内部指针。

假如让原型对象等于另一个类型的实例,结果会如何?显然,此时的原型对象包好一个指向另一个原型的指针,相应地,另一个原型中也包含着指向另一个函数的指针。假如另一个原型又是另一个类型的实例,上述关系依然成立,如此层层递进,构成了实例与原型的链条。这就是所谓原型链的基本概念。

function SuperType() {
    this.superProperty = true;
}
SuperType.prototype.getSuperProperty = function() {
    console.log(this.superProperty);
};
function SubType() {
    this.subProperty = false;
}
SubType.prototype = new SuperType();
SubType.prototype.getSubProperty = function() {
    console.log(this.subProperty);
};
var instance = new SubType();
instance.getSuperProperty();               //true

原型链模式的缺点:通过原型链实现继承时,原型实际上为另一个类型的实例,于是,原先的实例属性也变成了原型属性。而包含引用类型值的原型属性会被所有实例共享。

function SuperType() {
    this.superProperty = true;
    this.colors = ["red", "blue", "green"];
}
SuperType.prototype.getSuperProperty = function() {
    console.log(this.superProperty);
};
function SubType() {
    this.subProperty = false;
}
SubType.prototype = new SuperType();
SubType.prototype.getSubProperty = function() {
    console.log(this.subProperty);
};
var instance1 = new SubType();
instance1.colors.push("purple");
console.log(instance1.colors);            //["red", "blue", "green", "purple"]  var instance2 = new SubType();
console.log(instance2.colors);            //["red", "blue", "green", "purple"] 

为了解决原型链模式引用类型属性继承的问题,接下来讨论借用构造函数模式。

二. 借用构造函数模式

function SuperType() {
    this.colors = ["red", "blue", "green"];
}
function SubType() {
    SuperType.call(this);
}
var instance1 = new SubType();
instance1.colors.push("purple");
console.log(instance1.colors);      //["red", "blue", "green", "purple"]
var instance2 = new SubType();
console.log(instance2.colors);      //["red", "blue", "green"] 
相对于原型链,借用构造函数模式中,子类型的构造函数能够向父类型的构造函数传递参数。
function SuberType(name) {
    this.name = name;
}
function SubType(age) {
    SuberType.call(this,"Mars");
    this.age = age;
}
var instance = new SubType(27);
console.log(instance.name);            //Mars
console.log(instance.age);             //

借用构造函数模式的缺点:仅是借用构造函数,无法避免构造函数模式存在的问题——方法都在构造函数中定义,函数复用无从谈起。为解决这个问题,接下来讨论组合继承模式。

三. 组合继承

组合继承:原型链模式+借用构造函数模式,原型链模式实现对原型属性和方法的继承,借用构造函数模式实现对实例属性的继承。

function SuperType(name) {
    this.name = name;
    this.colors = ["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();
var instance1 = new SubType("Brittany",23);
instance1.colors.push("black");
console.log(instance1.colors);                  //["red", "blue", "green", "black"]
console.log(instance1.sayName());               //Brittany
var instance2 = new SubType("Closure",24);
console.log(instance2.colors);                  //["red", "blue", "green"]
console.log(instance2.sayName());               //Closure console.log(instance1 instanceof SubType);      //true
console.log(instance1 instanceof SuperType);    //true
console.log(SubType.prototype.isPrototypeOf(instance1));   //true
console.log(SuperType.prototype.isPrototypeOf(instance1)); //true

时间:2014-10-22

地点:合肥

引用:《JavaScript高级程序设计》

JavaScript 继承的更多相关文章

  1. javascript继承的三种模式

    javascript继承一般有三种模式:组合继承,原型式继承和寄生式继承: 1组合继承:javascript最为广泛的继承方式通过原型链实现对原型属性和方法的继承,通过构造函数实现对实例属性的继承,同 ...

  2. javascript继承机制的设计思想(ryf)

    我一直很难理解Javascript语言的继承机制. 它没有"子类"和"父类"的概念,也没有"类"(class)和"实例" ...

  3. 【读书笔记】javascript 继承

    在JavaScript中继承不像C#那么直接,C#中子类继承父类之后马上获得了父类的属性和方法,但JavaScript需要分步进行. 让Brid 继承 Animal,并扩展自己fly的方法. func ...

  4. 图解JavaScript 继承

    JavaScript作为一个面向对象语言,可以实现继承是必不可少的,但是由于本身并没有类的概念(不知道这样说是否严谨,但在js中一切都类皆是对象模拟)所以在JavaScript中的继承也区别于其他的面 ...

  5. JavaScript强化教程——Cocos2d-JS中JavaScript继承

    javaScript语言本身没有提供类,没有其它语言的类继承机制,它的继承是通过对象的原型实现的,但这不能满足Cocos2d-JS引擎的要求.由于Cocos2d-JS引擎是从Cocos2d-x演变而来 ...

  6. [原创]JavaScript继承详解

    原文链接:http://www.cnblogs.com/sanshi/archive/2009/07/08/1519036.html 面向对象与基于对象 几乎每个开发人员都有面向对象语言(比如C++. ...

  7. javascript继承(六)—实现多继承

    在上一篇javascript继承—prototype最优两种继承(空函数和循环拷贝)(3) ,介绍了js较完美继承的两种实现方案,那么下面来探讨一下js里是否有多继承,如何实现多继承.在这里可以看看j ...

  8. javascript继承(五)—prototype最优两种继承(空函数和循环拷贝)

    一.利用空函数实现继承 参考了文章javascript继承—prototype属性介绍(2) 中叶小钗的评论,对这篇文章中的方案二利用一个空函数进行修改,可以解决创建子类对象时,父类实例化的过程中特权 ...

  9. javascript继承(四)—prototype属性介绍

    js里每一个function都有一个prototype属性,而每一个实例都有constructor属性,并且每一个function的prototype都有一个constructor属性,这个属性会指向 ...

  10. 【JavaScript】重温Javascript继承机制

    上段时间,团队内部有过好几次给力的分享,这里对西风师傅分享的继承机制稍作整理一下,适当加了些口语化的描述,留作备案. 一.讲个故事吧 澄清在先,Java和Javascript是雷锋和雷峰塔的关系.Ja ...

随机推荐

  1. 一次U盘拯救的经历

    U盘拷资料,突然就弹出框框,复制终止了,然后U盘里面的只是编程可读的了. 倒是没有啥重要的资料,就是只有这一个U盘了,平时传资料都靠它,不能就这么垮了啊,于是就来了一次拯救行动. 一共有三个步骤 第一 ...

  2. 绝对炫的3D幻灯片-SLICEBOX

    绝对炫的3D幻灯片-SLICEBOX http://www.jq22.com/jquery-info31

  3. Asp.Net 一个请求的处理流程

    1.浏览器请求 请求-准备环境-->处理请求   2.Aspnet 环境的创建 客户请求 IIS区分静态文件还是动态文件,静态文件直接文件返回,动态文件通过aspnet_isapi.dll进行处 ...

  4. python走起之第十四话

    HTML 标题 HTML 标题(Heading)是通过<h1> - <h6> 标签来定义的. 实例 <h1>这是一个标题</h1> <h2> ...

  5. OpenLayers图形与列表互动

    项目上遇到这样一种需求:查询数据库后得到结果(带地理位置的)列表,每个结果在地图上都是一个四边形,四边形之间有交叉,有重叠,需要实现地图上的四边形和结果列表的互动.抛开其他逻辑功能,互动需求可以表示为 ...

  6. P​D​F​二​次​开​发​_​i​S​t​y​l​e​P​D​F​表​单​域​的​填​充

    wo讲到PDF表单,我们首先需要认识Adobe定义的PDF表单有哪些.以下是我从网上搜索到的简单介绍: PDF 表单简介 PDF 是可移植文档格式(Portable Document Format)的 ...

  7. DOM常用操作总结

    一.getElementById() 寻找一个有着给定 id 属性值的元素,返回值是一个有着给定 id 属性值的元素节点.如果不存在,这样的元素,它返回 null. 二.getElementsByNa ...

  8. hdu4449Building Design(三维凸包+平面旋转)

    链接 看了几小时也没看懂代码表示的何意..无奈下来问问考研舍友. 还是考研舍友比较靠谱,分分钟解决了我的疑问. 可能三维的东西在纸面上真的不好表示,网上没有形象的题解,只有简单"明了&quo ...

  9. MongoDB简介与增删改查

    一.简介 MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统.MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案.MongoDB 将数据存储为一个文档,数据 ...

  10. spring cloud资料

    https://segmentfault.com/a/1190000006216281 http://git.oschina.net/zhou666/spring-cloud-7simple zuul ...