今天学习js中的继承,《JavaScirpt高级程序设计》这本书真不错,学js的应该都有吧,呵呵
在JavaScript中,继承可以用四种方式实现,
1、对象冒充
感觉这种方式利用了js中类和函数的模糊性,同是function关键字申明方法,既可以说他是函数,也可以说他是类,js太灵活了,下面的例子说明下:
function ClassA(sColor){
this.color=sColor;
this.sayColor=function(){
alert(this.color);
}
}
function ClassB(sColor){
this.newMethod=ClassA;//把ClassA方法赋给newMethod.
this.newMethod();//调用newMethod.
delete this.newMethod;}
ClassB执行ClassA方法便相当于继承了ClassA,在调用完毕后要删除newMethod,因为后续添加的属性和方法如果和超类同名,就会覆盖超类的相关属性和方法。
利用这种继承方式可以实现多重继承,如:
多重继承
function ClassD(sColor){
this.newMethod=ClassA;//把ClassA方法赋给newMethod,
this.newMethod();//调用newMethod
delete this.newMethod;
this.newMethod=ClassB;
this.newMethod();
delete this.newMethod;}
利用这种多重继承方法有个弊端,如果ClassA和ClassB具有相同的属性和方法,ClassB有较高的优先级。
2、call方法和apply方法
由于第一种方法很流行,所以ECMAScript便function对象加入两个新方法,call()和apply(),这两中方法很相似,只有在传参方面有所不同,
call()方法的第一个参数用作this的对象,例如:
Call方法
function ClassB(sColor,sName){
ClassA.call(this,sColor);
this.name=sName;
this.sayName=function(){
alert(this.name);
}
}
call方法还是调用了ClassA()方法,利用this传递进去ClassB,为ClassB初始化,他仅仅是调用了ClassA()方法而已,如果你在ClassA之外为ClassA添加了方法(例如利用原型法),是不能继承到ClassB的。
call()方法的第一个参数必须是this,可以有第二个,第三个,第四个....参数。
apply()方法与call()方法不同的是,将二个,第三个,第四个....参数用一个数组传递。例如:
function ClassB(sColor,sName,sSex){
var arr=new Arry(sColor,sName,sSex);
ClassA.apply(this,arr);//传递数组
this.name=sName;
this.sayName=function(){
alert(this.name);
}
}
可以将arguments作为参数传递给apply,但是ClassB的参数顺序必须和ClassA一致。
3.原型链
利用prototype实现继承,prototype对象是个模板,要实例的对象都是以这个模板为基础,它的任何属性和方法都被传递给那个类的所有实例,原型链利用这种功能来实现继承机制。
如果利用原型方式实现继承,实例如下:
原型链
function ClassA(){
}
ClassA.prototype.color="red";
ClassA.prototype.sayColor=function(){
alert(this.color);
}
function ClassB(){
}
ClassB.prototype=newClassA();
通过原型链,ClassA的所有属性和方法传递给了ClassB,用prototype的确是方便很多。
注意的是调用ClassA的构造函数是,没有给它传递参数,这是在原型链中的标准做法。要确保构造函数没有任何参数。如果构造函数中有参数的话会怎样呢?那样便不能完全的继承,只能继承父类通过prototype初始的属性和方法,在构造函数中初始的属性和方法便不会继承。
与对象冒充相似,子类的所有属性和方法都必须出现在prototype属性被赋值之后,因为在它之前赋值的所有方法都会被删除。为什么呢?因为prototype属性被替换成了新的对象,原始对象的prototype属性以不复存在了,例如:
Code
function ClassB(){
}
ClassB.prototype=new ClassA();
ClassB.prototype.name="";
ClassB.prototype.sayName=function(){
alert(this.name);
}
原型链的弊端是不支持多重继承,需要记住的是,原型链会用另一个类型的对象重写类的prototype属性。
3.混合方式
使用原型链方法实现继承非常的方便,问题是不能够使用带参数的构造函数,通常使用构造函数来定义属性是最常见而且是最好的方式,要怎么做才可以好呢?
将对象冒充和原型链法结合起来使用,用对象冒充继承构造函数的属性,用原型链继承prototype对象的方法,用这种方式重写前面的例子,代码如下:
function ClassA(sColor){
this.color=sColor;
}
ClassA.prototype.sayColor=function(){
alert(this.color);
};
function ClassB(sColor,sName){
ClassA.call(this,sColor);
this.name=sName;
}
ClassB.prototype=new ClassA();
ClassB.prototype.sayName=function(){
alert(this.name);
};
function show()
{
var a=new ClassA("red");
var b=new ClassB("blue","lhy");
a.sayColor();//输出red
b.sayColor();//输出blue
b.sayName();//输出lhy
}
在此例子中,继承由两种方式实现,既使用了call方法,又使用了原型链,在构造函数中,用对象冒充继承ClassA类的sColor属性,在接下来的代码中利用原型链继承ClassA的方法,这样结合了对象冒充方法弥补了原型链法不能使用带参的构造函数的缺陷。
分享到:
相关推荐
几乎每个开发人员都有面向对象语言(比如C++、C#、Java)的开发经验。...但是在JavaScript的世界中,所有的这一切特性似乎都不存在。 因为JavaScript本身不是面向对象的语言,而是基于对象的语言。
javascript中如何实现封装,继承和多态
js继承实现示例代码,js继承实现示例代码,js继承实现示例代码
js没有特别明确的实现如何继承,但是能够通过特殊手段实现继承的,有四种方法
javascript中如何实现封装,继承和多态,并有详细,我天天在传谢谢
【JavaScript的9种继承实现方式归纳】js实现继承的几种方式.pdf
JS继承的实现方式转载整理。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
jQuery.js中继承的实现.pdf
使用js实现继承的七种方式,详细讲解了js中的原型链继承,构造函数继承,组合继承(经典继承),原型式继承,寄生式继承,寄生组合式继承,以及ES6中的继承,描述原理以及实现和要点概述等。
详细介绍了JavaScript中继承的实现方式以及其优缺点分析。
NULL 博文链接:https://raychase.iteye.com/blog/1337415
javascript做为一门脚本语言,但面向对象思想在其中也有体现,本文档阐述和总结了js中继承的实现,及个方法的利弊!
大多OO语言都支持两种继承方式: 接口继承和实现继承 ,而ECMAScript中无法实现接口继承,ECMAScript只支持实现继承,而且其实现继承主要是依靠原型链来实现,下文给大家技术js实现继承的六种方式,需要的朋友参考下
JS继承.txtJS继承.txtJS继承.txtJS继承.txtJS继承.txtJS继承.txtJS继承.txtJS继承.txtJS继承.txt
原型式继承 原型链式继承 借用构造函数(类式继承) 组合继承 寄生组合式继承 结束语 前言 对于灵活的js而言,继承相比于java等语言,继承实现方式可谓百花齐放。方式的多样就意味着知识点繁多,当然也是面试时...
详解Javascript继承的实现_.docx
JavaScript中基于原型的继承的实现与分析.pdf
利用javascript中的call实现继承
JavaScript继承的三种方法实例 继承 继承: 首先继承是一种关系,类(class)与类之间的关系,JS中没有类,但是可以通过构造函数模拟类,然后通过原型来实现继承。 继承也是为了数据共享,js中的继承也是为了实现...
javascript中如何实现封装,继承和多态,并有详细的示例.ppt