JS继承之原型继承
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继承之原型继承的更多相关文章
- JS中的原型继承机制
转载 http://blog.csdn.net/niuyongjie/article/details/4810835 在学习JS的面向对象过程中,一直对constructor与prototype感到很 ...
- js方法和原型继承(一)
在js语言规范中并不存在方法这一概念,方便起见,将作为对象属性的函数成为方法this引用的规则a.在最外层代码中,this引用的是全局对象b.在函数内,this引用根据函数调用方式不同而不同函数内部的 ...
- JS面向对象组件 -- 继承的其他方式(类式继承、原型继承)
继承的其他形式: •类式继承:利用构造函数(类)继承的方式 •原型继承:借助原型来实现对象继承对象 类 : JS是没有类的概念的 , 把JS中的构造函数看做的类 要做属性和方法继承的时候,要分开继 ...
- 关于js的对象原型继承(一)
javascript中,对象的继承是通过原型去继承. 可以这样理解:js中的对象,包含的除了属性和方法,还有一个最基本的原型__proto__对象.这个原型__proto__指向谁,这个对象就继承谁. ...
- JS高级. 03 混入式继承/原型继承/经典继承、拓展内置对象、原型链、创建函数的方式、arguments、eval、静态成员、实例成员、instanceof/是否在同一个原型链
继承:当前对象没有的属性和方法,别人有,拿来给自己用,就是继承 1 混入式继承 var I={ }; var obj = { name: 'jack', age:18, sayGoodbye : fu ...
- JS中的原型继承和多重继承
概念:1原型继承是创建新类型对象----子类型,子类型基于父类型,子类型拥有父类型所有的属性和方法(从父类型继承得到),然后修改其中的部分内容或者添加新的内容.继承最好在子类型模型可以被视为父类型对象 ...
- JavaScript 类式继承与原型继承
交叉着写Java和Javascript都有2年多了,今天来总结下自己所了解的Javascript类与继承. Javascript本身没有类似Java的面向对象的类与继承术语,但其基于原型对象的思想却可 ...
- js中的原型继承
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 关于js的对象原型继承(二)
本章讨论使用new一个构造函数来创建一个对象. 前期知识点说明: 1.prototype是函数的一个属性,每个函数都有一个prototype属性.这个属性是一个指针,指向一个对象.它是显示修改对象的原 ...
随机推荐
- 通过AngularJS实现前端与后台的数据对接(二)——服务(service,$http)篇
什么是服务? 服务提供了一种能在应用的整个生命周期内保持数据的方法,它能够在控制器之间进行通信,并且能保证数据的一致性. 服务是一个单例对象,在每个应用中只会被实例化一次(被$injector实例化) ...
- jquery.uploadify文件上传组件
1.jquery.uploadify简介 在ASP.NET中上传的控件有很多,比如.NET自带的FileUpload,以及SWFUpload,Uploadify等等,尤其后面两个控件的用户体验比较好, ...
- 一步步开发自己的博客 .NET版(11、Web.config文件的读取和修改)
Web.config的读取 对于Web.config的读取大家都很属性了.平时我们用得比较多的就是appSettings节点下配置.如: 我们对应的代码是: = ConfigurationManage ...
- .NET平台开源项目速览(13)机器学习组件Accord.NET框架功能介绍
Accord.NET Framework是在AForge.NET项目的基础上封装和进一步开发而来.因为AForge.NET更注重与一些底层和广度,而Accord.NET Framework更注重与机器 ...
- 11、Struts2 的文件上传和下载
文件上传 表单准备 要想使用 HTML 表单上传一个或多个文件 须把 HTML 表单的 enctype 属性设置为 multipart/form-data 须把 HTML 表单的method 属性设置 ...
- 【置顶】CoreCLR系列随笔
CoreCLR配置系列 在Windows上编译和调试CoreCLR GC探索系列 C++随笔:.NET CoreCLR之GC探索(1) C++随笔:.NET CoreCLR之GC探索(2) C++随笔 ...
- web api接口同步和异步的问题
一般来说,如果一个api 接口带上Task和 async 一般就算得上是异步api接口了. 如果我想使用异步api接口,一般的动机是我在我的方法里面可能使用Task.Run 进行异步的去处理一个耗时的 ...
- 编写高质量代码:改善Java程序的151个建议(第8章:多线程和并发___建议126~128)
建议126:适时选择不同的线程池来实现 Java的线程池实现从根本上来说只有两个:ThreadPoolExecutor类和ScheduledThreadPoolExecutor类,这两个类还是父子关系 ...
- 如果你也会C#,那不妨了解下F#(7):面向对象编程之继承、接口和泛型
前言 面向对象三大基本特性:封装.继承.多态.上一篇中介绍了类的定义,下面就了解下F#中继承和多态的使用吧.
- android SystemServer.java启动的服务。
EntropyService:熵(shang)服务,用于产生随机数PowerManagerService:电源管理服务ActivityManagerService:最核心服务之一,Activity管理 ...