js原型继承
2015-06-02 11:07
696 查看
继承是OO语言中一个重要的特性和概念。许多的OO语言中都支持两种继承方式:接口继承和实现继承。
ECMAScript只支持实现继承,其实现继承主要是靠原型链来实现。在PHP语言中,是使用extend来实现继承。那么我们就先来讲讲原型链。
原型链的基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。
简单回顾下构造函数、原型和实例的关系:
每个构造函数都有一个原型对象,原型对象包含一个指向构造函数的指针(prototype),而实例则包含一个指向原型对象的内部指针(__proto__)。
实现原型链有一种基本模式,其代码大致如下:
以上代码是定义了2个类型:SuperType()和SubType(),每个类型分别有一个属性和方法。2者的区别是SubType继承了SuperType。通过创建SuperType实例并将该实例赋给SubType.prototype。原来存在于SuperType中所有的属性和方法也都存在于SubType.prototype中了。在确立了这种继承关系后,又在SubType.prototype中添加了一个方法。
请看下图展示的实例以及构造函数和原型之间的关系:PS:找线画了半天没画好,先这么看吧:)
确定原型和实例的关系:
可以通过两种方式来确定原型和实例之间的关系。第一种方式是使用instanceof操作符;第二种是使用isPrototypeOf()方法。
原型链的问题:
虽然很强大,可以用它来实现继承,但它也存在一些问题。最主要的问题来自包含引用类型值的原型。在通过原型来实现继承时,原型实际上会变成一个类型的实例。于是,原先的实例属性也顺理成章的变成了现在的原型的属性了。看例子吧!
SuperType构造函数定义了一个属性,该属性包含一个数组(引用类型值)。当SubType通过原型继承了SuperType之后,SubType.prototype就变成了SuperType的一个实例。因此也拥有了SuperType的所有属性和方法。结果SubType会共享这个colors属性,我们通过对instance1.colors的修改,能够通过instance2.colors反映出来。
第二个问题是创建子类型的实例时,不能向超类型的构造函数中传递函数。鉴于这几点问题,实践中很少会单独使用原型链。
ECMAScript只支持实现继承,其实现继承主要是靠原型链来实现。在PHP语言中,是使用extend来实现继承。那么我们就先来讲讲原型链。
原型链的基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。
简单回顾下构造函数、原型和实例的关系:
每个构造函数都有一个原型对象,原型对象包含一个指向构造函数的指针(prototype),而实例则包含一个指向原型对象的内部指针(__proto__)。
实现原型链有一种基本模式,其代码大致如下:
function SuperType() { this.property = true; } SuperType.prototype.getSuperValue = function() { return this.property; }; function SubType() { this.subproperty = false; } //继承了SuperType SubType.prototype = new SuperType(); SubType.prototype.getSubValue = function() { return this.subproperty; }; var instance = new SubType(); alert(instance.getSubValue()); //true
以上代码是定义了2个类型:SuperType()和SubType(),每个类型分别有一个属性和方法。2者的区别是SubType继承了SuperType。通过创建SuperType实例并将该实例赋给SubType.prototype。原来存在于SuperType中所有的属性和方法也都存在于SubType.prototype中了。在确立了这种继承关系后,又在SubType.prototype中添加了一个方法。
请看下图展示的实例以及构造函数和原型之间的关系:PS:找线画了半天没画好,先这么看吧:)
确定原型和实例的关系:
可以通过两种方式来确定原型和实例之间的关系。第一种方式是使用instanceof操作符;第二种是使用isPrototypeOf()方法。
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
原型链的问题:
虽然很强大,可以用它来实现继承,但它也存在一些问题。最主要的问题来自包含引用类型值的原型。在通过原型来实现继承时,原型实际上会变成一个类型的实例。于是,原先的实例属性也顺理成章的变成了现在的原型的属性了。看例子吧!
function SuperType() { this.colors = ["red", "green", "blue"]; } function SubType() { } //继承了SuperType SubType.prototype = new SuperType(); var instance1 = new SubType(); instance1.colors.push("black"); alert(instance1.colors); //red,green,blue,black var instance2 = new SubType(); alert(instance2.colors); //red,green,blue,black
SuperType构造函数定义了一个属性,该属性包含一个数组(引用类型值)。当SubType通过原型继承了SuperType之后,SubType.prototype就变成了SuperType的一个实例。因此也拥有了SuperType的所有属性和方法。结果SubType会共享这个colors属性,我们通过对instance1.colors的修改,能够通过instance2.colors反映出来。
第二个问题是创建子类型的实例时,不能向超类型的构造函数中传递函数。鉴于这几点问题,实践中很少会单独使用原型链。
相关文章推荐
- javascript深入理解js闭包
- JS跳转到另一地址
- js 性能优化整理之 惰性载入
- Javascript中正则表达式详解(转载)
- 谈谈自己对js闭包,执行上下文,作用域链,活动对象AO,变量对象VO的理解
- JSON字符串写法和使用
- web开发常用的js验证,利用正则表达式验证邮箱、手机、身份证等输入
- 使用X-UA-Compatible来设置IE浏览器兼容模式
- 年月日时分秒加星期的即时显示的JS
- JS倒计时源码
- JavaScript 闭包初步
- shakejs是一个摇一摇的工具
- js 打印功能
- jsdoc注释规范工具(使用 JSDoc 3 自动生成 JavaScript API 文档)
- jsp 使用properties配置文件方法
- javascript压缩工具:YUI compressor
- 简单JS传出参数例子
- Newtonsoft.Json与datatables.net的使用 完美分页
- mas.js服务开启
- javascript Date format(js日期格式化)