许多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. 前端中sprite.png的实现

    通过background-position来控制X轴和Y轴,从而实现显示sprite.png中想要的ico或图案. 如下图所示:

  2. 【分享】图解Windows Server 2012 R2 配置IIS 8全过程

    最近计划更换服务器,包括IIS服务器与数据库服务器,操作系统都是Windows Server 2012 R2,第一次接触Windows Server 2012,感觉比较新鲜,一路摸索完成了IIS 8 ...

  3. Initializing connection provider: org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider停住了

    2015.1.24进行了服务器的搬家,搬家后,更换了新的IP,导致新的IP访问以前IP的数据库服务无法成功Initializing connection provider: org.springfra ...

  4. 上传文件创建目录 mkdir

    mkdir($save_path,0777,true); $save_path  :文件名 0777:权限 .windows 下面可以忽略 当创建多级文件目录的时候一定要加上 true

  5. ROS学习笔记(三)——ROS安装

    安装指南: indigo安装 http://wiki.ros.org/indigo/Installation/Ubuntu 中文参考教程: http://wiki.ros.org/cn 1.配置Uba ...

  6. 哈希表(Hash Table)

    参考: Hash table - Wiki Hash table_百度百科 从头到尾彻底解析Hash表算法 谈谈 Hash Table 我们身边的哈希,最常见的就是perl和python里面的字典了, ...

  7. centos5.11 repo 安装mysql5.7

    http://dev.mysql.com/doc/refman/5.7/en/linux-installation-yum-repo.html mysql yum repo 安装说明 http://d ...

  8. 一个div相对于外层的div水平和垂直居中

    我自己感觉,第四种比较常用 <title>无标题文档</title><style>        .parent {           width:800px; ...

  9. NGUI Atlas Maker sprites with black line issue

    NGUI图集中的图,在游戏中显示出来带有黑边的问题. 实际上是因为图片在导入到图集中,图片四周的完全透明的边缘部分会被裁掉,而在图集中的实际大小比图片原始大小小以及图集中图片之间的间距设置得太小导致. ...

  10. ionic实现双击返回键退出功能

    实现这个功能需要四个步骤: 步骤一: 说明:因为需要和手机的硬件(返回按钮)打交道,而ionic本身是不具备该功能的,但是有一个东西可以:ng-cordova插件,这个插件是phoneGap为了能让i ...