ECMAScript只支持实现继承,其实现继承主要是靠原型链来实现。

原型链的基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。

简单回顾下构造函数、原型和实例的关系:

每个构造函数都有一个原型对象,原型对象包含一个指向构造函数的指针(prototype),而实例则包含一个指向原型对象的内部指针(__proto__)。

实现原型链有一种基本模式,其代码大致如下:

function aa() {
this.boolean_1 = true;
}
aa.prototype.value = function() {
return this.boolean_1;
} function bb() {
this.boolean_2 = false;
}
//继承了aa
bb.prototype = new aa();
bb.prototype.value = function() {
return this.boolean_2
}
var A = new bb();
console.log(A.value())
console.log(aa.prototype.isPrototypeOf(A));
console.log(A instanceof Object);

以上代码是定义了2个类型:aa()和bb(),每个类型分别有一个属性和方法。2者的区别是bb继承了aa。通过创建aa实例并将该实例赋给bb.prototype。原来存在于aa中所有的属性和方法也都存在于bb.prototype中了。在确立了这种继承关系后,又在bb.prototype中添加了一个方法。

可以通过两种方式来确定原型和实例之间的关系。第一种方式是使用instanceof操作符;第二种是使用isPrototypeOf()方法。

当bb继承了aa后,结果为:

false
true
true

当把继承去掉后,结果为:

false
false
true

原型链的问题:

虽然很强大,可以用它来实现继承,但它也存在一些问题。最主要的问题来自包含引用类型值的原型。在通过原型来实现继承时,原型实际上会变成一个类型的实例。于是,原先的实例属性也顺理成章的变成了现在的原型的属性了。看例子吧!

function aa(){
this.colors=['red','blue','orange']
}
function bb(){}
bb.prototype=new aa();
var A=new bb();
A.colors.push('black');
console.log(A.colors); // ==> ["red", "blue", "orange", "black"]
var B=new bb();
console.log(B.colors); // ==> ["red", "blue", "orange", "black"]

aa构造函数定义了一个属性,该属性包含一个数组(引用类型值)。当bb通过原型继承了aa之后,bb.prototype就变成了aa的一个实例。因此也拥有了aa的所有属性和方法。结果bb会共享这个colors属性,我们通过对A.colors的修改,能够通过B.colors反映出来。

第二个问题是创建子类型的实例时,不能向超类型的构造函数中传递函数。鉴于这几点问题,实践中很少会单独使用原型链。

JS 面向对象之继承 -- 原型链的更多相关文章

  1. 关于JS面向对象中原型和原型链以及他们之间的关系及this的详解

    一:原型和原型对象: 1.函数的原型prototype:函数才有prototype,prototype是一个对象,指向了当前构造函数的引用地址. 2.函数的原型对象__proto__:所有对象都有__ ...

  2. js面向对象之继承-原型继承

    //animal 父类 超类 var Animal = function(name) { this.name = name; this.sayhello = function() { alert(&q ...

  3. JavaScript的面向对象原理之原型链详解

    一.引言 在16年的10月份,在校内双选会找前端实习的时候,hr问了一个问题:JavaScript的面向对象理解吗?我张口就说“JavaScript是基于原型的!”.然后就没什么好说的了,hr可能不知 ...

  4. JavaScript的面向对象原理之原型链

    二.JavaScript的对象 为了能够清楚的解释这一切,我先从对象讲起.从其他面向对象语言(如Java)而来的人可能认为在JS里的对象也是由类来实例化出来的,并且是由属性和方法组成的. 实际上在JS ...

  5. 第20篇 js高级知识---深入原型链

    前面把js作用域和词法分析都说了下,今天把原型链说下,写这个文章费了点时间,因为这个东西有点抽象,想用语言表达出来不是很容易,我想写的文章不是简单的是官方的API的copy,而是对自己的知识探索和总结 ...

  6. Javascript 组合继承 原型链继承 寄生继承

    Javascript继承通常有三种方式. 第一种:组合式继承: function SuperType(name) { this.name = name; this.colors = ["re ...

  7. 一篇文章理解JS继承——原型链/构造函数/组合/原型式/寄生式/寄生组合/Class extends

    说实在话,以前我只需要知道"寄生组合继承"是最好的,有个祖传代码模版用就行.最近因为一些事情,几个星期以来一直心心念念想整理出来.本文以<JavaScript高级程序设计&g ...

  8. js 继承 原型链

    这里先说基于原型链实现的继承.那首先就得明白什么是原型链了: 每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针. 那么,假如我们让原型对象等于 ...

  9. JS继承——原型链

    许多OO语言支持两种继承:接口继承和实现继承.ECMAScript只支持实现继承,且继承实现主要依赖原型链实现. 原型链 基本思想:利用原型让一个引用类型继承另一个引用类型的属性和方法. 构造函数.原 ...

随机推荐

  1. Velocity语法大全

    1\ 参考地址:http://www.cnblogs.com/codingsilence/archive/2011/03/29/2146580.html

  2. 3月2日 Linked List Cycle

    今天星期天,准备好周一的PPT内容,再回来做题,以后考虑周末做一个APP或者微信帐号玩吧. 回到题目, Linked List Cycle,一个检查单项链表是否有环路的问题. 题目周五的时候就简单做过 ...

  3. php中实现17种正则表达式

    php中实现17种正则表达式 该教程来自:php教程网:http://php.662p.com "^\d+[ DISCUZ_CODE_1 ]quot; //非负整数(正整数 + 0) &qu ...

  4. 对象之间的引用传递 之 .NET中的深拷贝和浅拷贝

    1.场景 首先,场景是这样的. 有一个Person类,类中有一个类型是Car的属性.用于表述,人开的车. Car类中有一些描述诸如汽车拼盘之类的属性.基本场景就是这样.   2.浅拷贝 Person ...

  5. SQLServer中用户 'sa' 登录失败解决办法

    今天下午,很奇怪的网站突然就打不开了,报错如下: “/”应用程序中的服务器错误. 用户 'sa' 登录失败. 说明: 执行当前 Web 请求期间,出现未处理的异常.请检查堆栈跟踪信息,以了解有关该错误 ...

  6. SQL Server存储过程(转载)

    Transact-SQL中的存储过程,非常类似于Java语言中的方法,它可以重复调用.当存储过程执行一次后,可以将语句缓存中,这样下次执行的时候直接使用缓存中的语句.这样就可以提高存储过程的性能. Ø ...

  7. 在EF的code frist下写稳健的权限管理系统:仓储设计(三)

    public class BaseRepository<T>:IBaseRepository<T> where T : class { protected EfConnecti ...

  8. jquery.validate新的写法(jquery.validate1.13.js)

    <script src="../js/jquery.js"></script> <script src="../js/jquery.vali ...

  9. python 函数对象(函数式编程 lambda、map、filter、reduce)、闭包(closure)

    1.函数对象 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 秉承着一切皆对象的理念,我们再次回头来看函数(function).函 ...

  10. 《Prism 5.0源码走读》Service Locator Pattern

    在Prism Bootstrapper里面取实例的时候使用 ServiceLocator模式,使用的是CommonServiceLocator库 (http://commonservicelocato ...