作者:张维,引用请注明来源
javascript是基于对象的编程语言,但是它面向对象的特性并没有实现完全.
每个脚本解释器,和不同的运行环境,都会有不同的面向对象实现,不同保证相互兼容
.如NODEJS,以及IE,FF,CHROME等环境.
笔者今天发表自己的继承写法,希望大家一起讨论
这个写法可能会有点麻烦,因为需要可能改变了很多人的JS编程习惯.
但是可以确保兼容.同时也注意了滥用prototype的问题,避免一些BUG和性能问题
因为以往在prototype中直接创建对象的方式来绑定,
会有多余对象生产可能会多余的调用构造函数,还会产生BUG,(在你不想调用的时候调用了)
ChildClass.prototype = new ParentClass();//说的是这种写法
下面,直接上代码
<pre class="javascript" name="code" code_snippet_id="142810" snippet_file_name="blog_20140105_1_5616986">function log(msg){
if(typeof window != "undefined"){
document.write(msg + "<br />");
}else{
console.log(msg);
}
}
///////////begin animal
function Animal(aName)
{
this.constructor(aName);
}
//Animal.prototype.base_constructor = function(){};
Animal.prototype.constructor = Animal_constructor;
Animal.count = 0;//静态成员变量
Animal.getCount = Animal_getCount;//静态方法
function Animal_constructor(aName){
//this.base_constructor();
log("Animal_constructor");
//成员变量在下面绑定
this.name = aName;
this.weight = 10;
//成员方法在下面绑定
this.move = Animal_move;
this.hit = Animal_hit;
Animal.count++;
}
function Animal_move(){
log("Animal_move");
}
function Animal_hit(){
log("Animal_hit");
}
function Animal_getCount(){
return Animal.count;
}
/////////////end animal
/////////begin cat
function Cat(aName, aColor){
//调用基类构造函数,这是真正产生继承效用的地方
//同时,继承可以是无限级的,因为这种作法将递归调用每个祖宗类的构造函数
this.constructor(aName, aColor);
}
Cat.prototype.base_constructor = Animal_constructor;
//这一行非常关键,继承关系就在这边体现,表示猫继承动物基类
Cat.prototype.constructor = Cat_constructor;
Cat.footCount = 4;//猫科动物都有4条腿
Cat.count = 0;//猫类自己的静态变量count,与父类是相互独立的
function Cat_constructor(aName, aColor){
this.base_constructor(aName);
log("Cat_constructor");
//成员变量列表
this.color = aColor;
//成员方法列表
this.hit = Cat_hit;//重写了一个方法
Cat.count++;
}
//Cat类重写hit方法的定义
function Cat_hit(){
log("Cat_hit");
}
///////////end cat
var xAnimal = new Animal("someone");
//调用一次Animal的构造函数
var xCat = new Cat("Tom","gray");
//这一步将先调用Animal的构造函数
//再调用Cat的构造函数
log(xCat.name);
//输出:Tom
//说明Cat类使用了这个属性的默认值
log(xCat.color);
//输出:gray
xCat.move();
//输出:Animal_move
//说明调用了基类的方法
xCat.hit();
//输出:Cat_hit
//说明调用的是自己重写的方法
Animal_hit.apply(xCat,null);
//输出:Animal_hit
//我也觉得这种方式来调用父类麻烦,希望大家给建议改进
log(Animal.count);
//输出:2
//说明每一个动物以及派生类的构造都让Animal的静态成员count增长1次
log(Cat.count);
//输出:1
//说明父类和子类的静态变量是相互独立的