JavaScript中子类调用父类方法

很久之前就在用JavaScript了,只是用的比较表层,会写几个函数而已,也没有深入的研究过。最近一段时间,由于项目的需要,看了一些关于JavaScript的书,也写了不少的JavaScript的代码,慢慢开始对这个东东着迷了。现在JavaScript在Web应用中的比重越来越大,各种好用的库也层出不穷,即使对JavaScript了解的比较浅显,也可以利用各种利器做出很不错的作品。但是,较为深入的了解一下JavaScript的特性,对于更熟练的使用它肯定还是有很大的帮助的。

JavaScript是一种基于原型(prototype-based)的语言,而Java是基于类(class-based)的语言。对于我这种先学习Java再学习JavaScript的人来说,总是会不自觉的用一些Java的概念去往JavaScript上套用。比如说,我就很想在JavaScript中使用类似Java中super.someMethod()。但是很多JavaScript的资料上最常见的写法是:

someObject.prototype.someMethod = function(){…};

这样就是完全改写了父类的方法,是无法满足需求的。

借助JavaScript中的apply或者call,就可以实现在子类中调用父类方法。

假设如下场景:根据不同的数据对生成的图形进行不同形式的填充。父类负责生成基本的图形,子类根据需求对父类生成的图像进行填充。

代码如下:

<html>

<head>

<meta content="text/html; charset=UTF-8"/>

<script type="text/javascript">

Shape = function() {

this.id = null;

this.picture = null;

this.draw = function(canvas){

this.picture = "由父类产生的图像已经生成在画布上了";

};

};

CommonShape = function(){};

CommonShape.prototype = new Shape();

CrossFillShape = function(){

this.draw = function(canvas){

CrossFillShape.prototype.draw.apply(this, arguments);

this.picture = this.picture + ", 然后被子类 CrossFillShape 填充";

};

};

CrossFillShape.prototype = new Shape();

SolidFillShape = function(){

this.draw = function(canvas){

SolidFillShape.prototype.draw.apply(this, arguments);

this.picture = this.picture + ", 然后被子类 SolidFillShape 填充";

};

};

SolidFillShape.prototype = new Shape();

function test1() {

var s = new CommonShape();

s.draw();

console.debug(s.picture);

var cs = new CrossFillShape();

cs.draw();

console.debug(cs.picture);

var ss = new SolidFillShape();

ss.draw();

console.debug(ss.picture);

}

</script>

</head>

<body>

<input type="button" value="test1" onclick="test1()"/><br/>

</body>

</html>

(上面代码中的console对象是Firefox的Firebug插件提供的,在这里为Firebug插件做个广告,那是相当的好用啊!)

这里通过apply来调用父类方法。

JavaScript中的apply和call

在JavaScript中,一个对象方法代码中的this并不是一直指向这个对象,通过apply或者call就可以方便的切换this指向的方法。或者说,apply和call方法的最直接的作用就是切换this的指向,并由此可以引发很多非常灵活的用法(可以看看prototype库的代码,有很多apply和call)。apply和call的区别在于调用时参数传入的方式不同:第一个参数都是对象指针(也就是说把原来代码中的this指向哪个对象),apply的第二个参数是数组,call从第二个参数开始是实际的函数调用参数

可以用下面的式子表达:

foo.call(this, arg1,arg2,arg3) == foo.apply(this, arguments) == this.foo(arg1, arg2, arg3)

转自:http://www.blogjava.net/yoda/archive/2010/04/29/319728.html