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

                                             --摘自《JavaScript高级程序设计》
原型继承
原型链是实现原型继承的主要方法,基本思想就是利用原型让一个引用类型继承另一个引用类型的属性和方法。
 
实现原型链的基本模式:
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.property; }
var instance=new SubType();
instance.getSuperValue(); //true;

例子中的实例及构造函数和原型之间的关系图:

在例子代码中,定义了两个对象,subType和superType。

两个对象之间实现了继承,而这种继承方式是通过创建SuperType的实例并将该实例赋给subType.prototype实现的。实现的本质就是重写了原型对象

这样subType.prototype中就会存在一个指针指向superType的原型对象。也就是说,存在superType的实例中的属性和方法现在都存在于subType.prototype中了。这样继承了之后,又可以为subType添加新的方法和属性。

要注意,这个指针([[prototype]])默认情况下是不可以再被外部访问的,估计是会被一些内部方法使用的,例如用for...in来遍历原型链上可以被枚举的属性的时候,就需要通过这个指针找到当前对象所继承的对象。不过,Firefox、Safari和Chrome在每个对象上都支持一个属性__proto__。

原型继承需要注意的一些问题

1.别忘记默认的类型

我们知道,所有的引用类型都继承了Object,而这个继承也是通过原型链实现的。所以所有的对象都拥有Object具有的一些默认的方法。如

:hasOwnProperty()、propertyIsEnumerable()、toLocaleString()、toString()和valueOf()。

2. 确定原型和实例的关系
可以通过两种方式来确定原型和实例之间的关系。

①使用instanceof 操作符,只要用这个操作符来测试实例与原型链中出现过的构造函数,结果就会返回true。

②第二种方式是使用isPrototypeOf()方法。同样,只要是原型链中出现过的原型,都可以说是该原型链所派生的实例的原型,因此isPrototypeOf()方法也会返回true。

例子:

alert(instance instanceof Object); //true
alert(instance instanceof SuperType); //true
alert(instance instanceof SubType); //true

alert(Object.prototype.isPrototypeOf(instance)); //true
alert(SuperType.prototype.isPrototypeOf(instance)); //true
alert(SubType.prototype.isPrototypeOf(instance)); //true

③子类要在继承后定义新方法

因为,原型继承是实质上是重写原型对象。所以,如果在继承前就在子类的prototype上定义一些方法和属性。那么继承的时候,子类的这些属性和方法将会被覆盖。

如图:

④不能使用对象字面量创建原型方法

这个的原理跟第三点的实际上是一样的。当你使用对象字面量创建原型方法重写原型的时候,实质上相当于重写了原型链,所以原来的原型链就被切断了。

⑤注意父类包含引用类型的情况

如图:

这个例子中的SuperType 构造函数定义了一个colors 属性,该属性包含一个数组(引用类型值)。SuperType 的每个实例都会有各自包含自己数组的colors 属性。当SubType 通过原型链继承了SuperType 之后,SubType.prototype 就变成了SuperType 的一个实例,因此它也拥有了一个它自己的colors 属性——就跟专门创建了一个SubType.prototype.colors 属性一样。但结果是什么呢?结果是SubType 的所有实例都会共享这一个colors 属性。而我们对instance1.colors 的修改能够通过instance2.colors 反映出来。也就是说,这样的修改会影响各个实例。

原型继承的缺点(问题)

①最明显的就是上述第⑤点,有引用类型的时候,各个实例对该引用的操作会影响其他实例。

②没有办法在不影响所有对象实例的情况下,给超类型的构造函数传递参数。

有鉴于此,实践中很少会单独使用原型继承。

最近要回顾一下原生js的一些重要的基础知识点,秋招秋招。。。

JS继承之原型继承的更多相关文章

  1. JS中的原型继承机制

    转载 http://blog.csdn.net/niuyongjie/article/details/4810835 在学习JS的面向对象过程中,一直对constructor与prototype感到很 ...

  2. js方法和原型继承(一)

    在js语言规范中并不存在方法这一概念,方便起见,将作为对象属性的函数成为方法this引用的规则a.在最外层代码中,this引用的是全局对象b.在函数内,this引用根据函数调用方式不同而不同函数内部的 ...

  3. JS面向对象组件 -- 继承的其他方式(类式继承、原型继承)

    继承的其他形式: •类式继承:利用构造函数(类)继承的方式 •原型继承:借助原型来实现对象继承对象   类 : JS是没有类的概念的 , 把JS中的构造函数看做的类 要做属性和方法继承的时候,要分开继 ...

  4. JS中的原型继承和多重继承

    概念:1原型继承是创建新类型对象----子类型,子类型基于父类型,子类型拥有父类型所有的属性和方法(从父类型继承得到),然后修改其中的部分内容或者添加新的内容.继承最好在子类型模型可以被视为父类型对象 ...

  5. JavaScript 类式继承与原型继承

    交叉着写Java和Javascript都有2年多了,今天来总结下自己所了解的Javascript类与继承. Javascript本身没有类似Java的面向对象的类与继承术语,但其基于原型对象的思想却可 ...

  6. JS原型继承和类式继承

    前言 一个多月前,卤煮读了一篇翻译过来的外国人写的技术博客.此君在博客中将js中的类(构造)继承和原型继承做了一些比较,并且得出了结论:建议诸位在开发是用原型继承.文中提到了各种原型继承的优点,详细的 ...

  7. javascript实现继承3种方式: 原型继承、借用构造函数继承、组合继承,模拟extends方法继承

    javascript中实现继承的三种方式:原型继承.借用构造函数继承.混合继承: /* js当中的继承 js中 构造函数 原型对象 实力对象的关系: 1 构造函数.prototype = 原型对象 2 ...

  8. call()和原型继承的方法

    1.call() call()方法接受两个参数,obj和arg 比如functionA.call(obj,arg)   就是说现在运行(执行)functionA这个方法,但是functionA里面的方 ...

  9. JS面向对象(2) -- this的使用,对象之间的赋值,for...in语句,delete使用,成员方法,json对象的使用,prototype的使用,原型继承与原型链

    相关链接: JS面向对象(1) -- 简介,入门,系统常用类,自定义类,constructor,typeof,instanceof,对象在内存中的表现形式 JS面向对象(2) -- this的使用,对 ...

随机推荐

  1. 洛谷 P2726 阶乘 Factorials Label:Water

    题目背景 N的阶乘写作N!,表示小于等于N的所有正整数的乘积. 题目描述 阶乘会变大得很快,如13!就必须用32位整数类型来存储,到了70!即使用浮点数也存不下了. 你的任务是找到阶乘最前面的非零位. ...

  2. centos ADSL 拨号上网设置

    下面主要介绍一下,在CentOS命令行环境下如何配置 ADSL 联网: 1.确保安装了网卡并能正常运行,使用命令查看一下网卡状态: [root@localhost simon]# /sbin/ifco ...

  3. 让sql语句不排序,按照in语句的顺序返回结果

    SELECT * FROM EVENT WHERE eventId IN(443,419,431,440,420,414,509)  ORDER BY INSTR(',443,419,431,440, ...

  4. Latex 学习

    Latex 学习 @(05.2 Latex)[latex][基础教程] 这篇文章是关于latex基础教程.pdf的一个总结. 基本知识 基础 1. 空格 多个空格会被视为一个空格 单个回车会被视为一个 ...

  5. FFTW中文参考

    据说FFTW(Fastest Fourier Transform in the West)是世界上最快的FFT.为了详细了解FFTW以及为编程方便,特将用户手册看了一下,并结合手册制作了以下FFTW中 ...

  6. BZOJ3829 : [Poi2014]FarmCraft

    d[x]表示走完x的子树并回到x所需的时间 f[x]表示从走到x开始计时,x子树中最晚的点安装完的最早时间 d[x]=sum(d[i]+2),i是x的孩子 f[x]的计算比较复杂: 考虑将x的各棵子树 ...

  7. Git一张图学习

  8. Windows 错误代码

    Error Messages for Windows http://www.gregorybraun.com/MSWINERR.ZIP Server 4.0 Error Messages   Code ...

  9. XMPP协议、IM、客户端互联详解

    导读 对于推送,IM服务器,目前可以使用一些厂家提供的SDK来实现,但是我们的老板又总是担心使用别人的SDK,假如别人的服务出现问题,或者别人偷看咱们的信息,那岂不是出现很大问题了 聊一聊xmpp的服 ...

  10. codevs 1743 反转卡片

    题目描述 Description [dzy493941464|yywyzdzr原创] 小A将N张卡片整齐地排成一排,其中每张卡片上写了1~N的一个整数,每张卡片上的数各不相同. 比如下图是N=5的一种 ...