JavaScript 继承
许多OO语言都支持两种继承方式,接口继承和实现继承。接口继承只继承方法签名,而实现继承则继承实际的方法。由于在ECMAScript中,函数没有签名,无法实现接口继承,只支持实现继承,而且其实现继承主要是通过原型链来实现的。
一. 原型链模式
利用原型让引用类型继承另一个引用类型的属性和方法。
原型、构造函数和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针, 而实例包含一个指向原型对象的内部指针。
假如让原型对象等于另一个类型的实例,结果会如何?显然,此时的原型对象包好一个指向另一个原型的指针,相应地,另一个原型中也包含着指向另一个函数的指针。假如另一个原型又是另一个类型的实例,上述关系依然成立,如此层层递进,构成了实例与原型的链条。这就是所谓原型链的基本概念。
function SuperType() {
this.superProperty = true;
}
SuperType.prototype.getSuperProperty = function() {
console.log(this.superProperty);
};
function SubType() {
this.subProperty = false;
}
SubType.prototype = new SuperType();
SubType.prototype.getSubProperty = function() {
console.log(this.subProperty);
};
var instance = new SubType();
instance.getSuperProperty(); //true
原型链模式的缺点:通过原型链实现继承时,原型实际上为另一个类型的实例,于是,原先的实例属性也变成了原型属性。而包含引用类型值的原型属性会被所有实例共享。
function SuperType() {
this.superProperty = true;
this.colors = ["red", "blue", "green"];
}
SuperType.prototype.getSuperProperty = function() {
console.log(this.superProperty);
};
function SubType() {
this.subProperty = false;
}
SubType.prototype = new SuperType();
SubType.prototype.getSubProperty = function() {
console.log(this.subProperty);
};
var instance1 = new SubType();
instance1.colors.push("purple");
console.log(instance1.colors); //["red", "blue", "green", "purple"] var instance2 = new SubType();
console.log(instance2.colors); //["red", "blue", "green", "purple"]
为了解决原型链模式引用类型属性继承的问题,接下来讨论借用构造函数模式。
二. 借用构造函数模式
function SuperType() {
this.colors = ["red", "blue", "green"];
}
function SubType() {
SuperType.call(this);
}
var instance1 = new SubType();
instance1.colors.push("purple");
console.log(instance1.colors); //["red", "blue", "green", "purple"]
var instance2 = new SubType();
console.log(instance2.colors); //["red", "blue", "green"]
function SuberType(name) {
this.name = name;
}
function SubType(age) {
SuberType.call(this,"Mars");
this.age = age;
}
var instance = new SubType(27);
console.log(instance.name); //Mars
console.log(instance.age); //
借用构造函数模式的缺点:仅是借用构造函数,无法避免构造函数模式存在的问题——方法都在构造函数中定义,函数复用无从谈起。为解决这个问题,接下来讨论组合继承模式。
三. 组合继承
组合继承:原型链模式+借用构造函数模式,原型链模式实现对原型属性和方法的继承,借用构造函数模式实现对实例属性的继承。
function SuperType(name) {
this.name = name;
this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function() {
console.log(this.name);
};
function SubType(name,age) {
SuperType.call(this,name);
this.age = age;
}
SubType.prototype = new SuperType();
var instance1 = new SubType("Brittany",23);
instance1.colors.push("black");
console.log(instance1.colors); //["red", "blue", "green", "black"]
console.log(instance1.sayName()); //Brittany
var instance2 = new SubType("Closure",24);
console.log(instance2.colors); //["red", "blue", "green"]
console.log(instance2.sayName()); //Closure console.log(instance1 instanceof SubType); //true
console.log(instance1 instanceof SuperType); //true
console.log(SubType.prototype.isPrototypeOf(instance1)); //true
console.log(SuperType.prototype.isPrototypeOf(instance1)); //true
时间:2014-10-22
地点:合肥
引用:《JavaScript高级程序设计》
JavaScript 继承的更多相关文章
- javascript继承的三种模式
javascript继承一般有三种模式:组合继承,原型式继承和寄生式继承: 1组合继承:javascript最为广泛的继承方式通过原型链实现对原型属性和方法的继承,通过构造函数实现对实例属性的继承,同 ...
- javascript继承机制的设计思想(ryf)
我一直很难理解Javascript语言的继承机制. 它没有"子类"和"父类"的概念,也没有"类"(class)和"实例" ...
- 【读书笔记】javascript 继承
在JavaScript中继承不像C#那么直接,C#中子类继承父类之后马上获得了父类的属性和方法,但JavaScript需要分步进行. 让Brid 继承 Animal,并扩展自己fly的方法. func ...
- 图解JavaScript 继承
JavaScript作为一个面向对象语言,可以实现继承是必不可少的,但是由于本身并没有类的概念(不知道这样说是否严谨,但在js中一切都类皆是对象模拟)所以在JavaScript中的继承也区别于其他的面 ...
- JavaScript强化教程——Cocos2d-JS中JavaScript继承
javaScript语言本身没有提供类,没有其它语言的类继承机制,它的继承是通过对象的原型实现的,但这不能满足Cocos2d-JS引擎的要求.由于Cocos2d-JS引擎是从Cocos2d-x演变而来 ...
- [原创]JavaScript继承详解
原文链接:http://www.cnblogs.com/sanshi/archive/2009/07/08/1519036.html 面向对象与基于对象 几乎每个开发人员都有面向对象语言(比如C++. ...
- javascript继承(六)—实现多继承
在上一篇javascript继承—prototype最优两种继承(空函数和循环拷贝)(3) ,介绍了js较完美继承的两种实现方案,那么下面来探讨一下js里是否有多继承,如何实现多继承.在这里可以看看j ...
- javascript继承(五)—prototype最优两种继承(空函数和循环拷贝)
一.利用空函数实现继承 参考了文章javascript继承—prototype属性介绍(2) 中叶小钗的评论,对这篇文章中的方案二利用一个空函数进行修改,可以解决创建子类对象时,父类实例化的过程中特权 ...
- javascript继承(四)—prototype属性介绍
js里每一个function都有一个prototype属性,而每一个实例都有constructor属性,并且每一个function的prototype都有一个constructor属性,这个属性会指向 ...
- 【JavaScript】重温Javascript继承机制
上段时间,团队内部有过好几次给力的分享,这里对西风师傅分享的继承机制稍作整理一下,适当加了些口语化的描述,留作备案. 一.讲个故事吧 澄清在先,Java和Javascript是雷锋和雷峰塔的关系.Ja ...
随机推荐
- road习题(一)
答案:[D] 答案:[C] 分析需要靠人 答案:[B] 答案:[B] c语言本身支持自定义函数 答案:[B] Virtual User Generator:是一个脚本开发组件 说白了就是虚拟机用户发生 ...
- JAVA 1.7 流程控制语句 续
1. Java中的循环控制语句一共有3种,分别是while,do… while以及for循环.2. while循环,形式为:while(布尔表达式){//待执行的代码}3. do…while循环,新式 ...
- iOS 工程功能实现之好用的第三方
1.http://www.cocoachina.com/ios/20140224/7868.html (一个天气App案例) LBBlurredImage是一个继承自UIImageView,轻而易举 ...
- LVS DR模式 负载均衡服务搭建
LVS 负载均衡 最近在研究服务器负载均衡,阅读了网上的一些资料,发现主要的软件负载均衡方案有nginx(针对HTTP服务的负载均衡),LVS(针对IP层,MAC层的负载均衡).LVS模式工作在网络层 ...
- ASP.NET 页面间传递参数的方法
http://www.cnblogs.com/eoiioe/archive/2008/04/08/1142247.html
- SQL优化有偿服务
本人目前经营MySQL数据库的SQL优化服务,100块钱一条.具体操作模式 其中第一条,可以通过在微信朋友圈转发链接中的信息(http://www.yougemysqldba.com/discuz/v ...
- Oracle 表连接
Oracle 表之间的连接分为三种: 1. 内连接(自然连接) 2. 外连接 (1)左外连接 (左边的表不加限制) (2)右外连接(右边的表不加限制) (3)全外连接(左右两表都不 ...
- 初始JavaScript
本文是笔者在看廖雪峰老师的JavaScript教程时的总结 一.加载 JavaScript 1.直接在html语句中写入JavaScript语句 2.在html ...
- occ代码分析
临时变量就是local里面的变量擦除变量就是把模型改成擦除标记 void SelectMgr_SelectionManager::LoadMode (const Handle(SelectMgr_Se ...
- Spring MVC常用注解
cp by http://www.cnblogs.com/leskang/p/5445698.html 1.@Controller 在SpringMVC 中,控制器Controller 负责处理由Di ...