许多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的对象原型继承(一)

    javascript中,对象的继承是通过原型去继承. 可以这样理解:js中的对象,包含的除了属性和方法,还有一个最基本的原型__proto__对象.这个原型__proto__指向谁,这个对象就继承谁. ...

  5. JS高级. 03 混入式继承/原型继承/经典继承、拓展内置对象、原型链、创建函数的方式、arguments、eval、静态成员、实例成员、instanceof/是否在同一个原型链

    继承:当前对象没有的属性和方法,别人有,拿来给自己用,就是继承 1 混入式继承 var I={ }; var obj = { name: 'jack', age:18, sayGoodbye : fu ...

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

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

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

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

  8. js中的原型继承

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. 关于js的对象原型继承(二)

    本章讨论使用new一个构造函数来创建一个对象. 前期知识点说明: 1.prototype是函数的一个属性,每个函数都有一个prototype属性.这个属性是一个指针,指向一个对象.它是显示修改对象的原 ...

随机推荐

  1. 通过AngularJS实现前端与后台的数据对接(二)——服务(service,$http)篇

    什么是服务? 服务提供了一种能在应用的整个生命周期内保持数据的方法,它能够在控制器之间进行通信,并且能保证数据的一致性. 服务是一个单例对象,在每个应用中只会被实例化一次(被$injector实例化) ...

  2. jquery.uploadify文件上传组件

    1.jquery.uploadify简介 在ASP.NET中上传的控件有很多,比如.NET自带的FileUpload,以及SWFUpload,Uploadify等等,尤其后面两个控件的用户体验比较好, ...

  3. 一步步开发自己的博客 .NET版(11、Web.config文件的读取和修改)

    Web.config的读取 对于Web.config的读取大家都很属性了.平时我们用得比较多的就是appSettings节点下配置.如: 我们对应的代码是: = ConfigurationManage ...

  4. .NET平台开源项目速览(13)机器学习组件Accord.NET框架功能介绍

    Accord.NET Framework是在AForge.NET项目的基础上封装和进一步开发而来.因为AForge.NET更注重与一些底层和广度,而Accord.NET Framework更注重与机器 ...

  5. 11、Struts2 的文件上传和下载

    文件上传 表单准备 要想使用 HTML 表单上传一个或多个文件 须把 HTML 表单的 enctype 属性设置为 multipart/form-data 须把 HTML 表单的method 属性设置 ...

  6. 【置顶】CoreCLR系列随笔

    CoreCLR配置系列 在Windows上编译和调试CoreCLR GC探索系列 C++随笔:.NET CoreCLR之GC探索(1) C++随笔:.NET CoreCLR之GC探索(2) C++随笔 ...

  7. web api接口同步和异步的问题

    一般来说,如果一个api 接口带上Task和 async 一般就算得上是异步api接口了. 如果我想使用异步api接口,一般的动机是我在我的方法里面可能使用Task.Run 进行异步的去处理一个耗时的 ...

  8. 编写高质量代码:改善Java程序的151个建议(第8章:多线程和并发___建议126~128)

    建议126:适时选择不同的线程池来实现 Java的线程池实现从根本上来说只有两个:ThreadPoolExecutor类和ScheduledThreadPoolExecutor类,这两个类还是父子关系 ...

  9. 如果你也会C#,那不妨了解下F#(7):面向对象编程之继承、接口和泛型

    前言 面向对象三大基本特性:封装.继承.多态.上一篇中介绍了类的定义,下面就了解下F#中继承和多态的使用吧.

  10. android SystemServer.java启动的服务。

    EntropyService:熵(shang)服务,用于产生随机数PowerManagerService:电源管理服务ActivityManagerService:最核心服务之一,Activity管理 ...