JavaScript的面向对象编程相比其他语言确实比较麻烦。之前看到,单是类的定义就有很多种方式,而类的继承也有很多方式。这是因为JavaScript中的继承机制并不是明确规定的,而是通过模仿实现的。现把书上提到的方法总结如下代码.其中需要注意的重点已经作为注释标明。其中第五种——混合方式对应定义类的方法中的混合构造函数/原型方式,所以也是最佳的方式。 要用ECMAScript实现继承机制,首先要从基类入手。所有开发者定义的类都可以做外基类。出于安全考虑,本地类和宿主类不能所为基类,这样可以避免访问编译过的浏览器级的代码。
//此文件说明JavaScript中几种类的继承机制
//函数 extendsmethodn(n=1:5) 仅为分割代码和测试方便,实际继承方式仅为函数内的代码
//extendsmethod5();
//1、对象冒充(call方法和apply方法其实也可看做对象冒充)
function extendsmethod1(){
function ClassA(sColor){
this.color = sColor;
this.sayColor = function(){
alert(this.color);
};
}
function ClassB(sColor, sName){
this.newMethod = ClassA;
this.newMethod(sColor); //此处调用传递给ClassB的ClassA方法
delete this.newMethod;
//新的属性都要在删除父类对象后再定义
this.name = sName;
this.sayName = function(){
alert(this.name);
};
}
//测试
var objA = new ClassA("red");
var objB = new ClassB("blue", "Nicholas");
objA.sayColor();
//objA.sayName(); 这句会导致错误,ClassA类没有sayName方法。
objB.sayColor();
objB.sayName();
//继承多个类,假设已存在 ClassX ClassY两个类
/*
function ClassZ(){
this.newMethod = ClassX;
this.newMethod();
delete this.newMethod;
this.newMethod = ClassY;
this.newMethod();
delete this newMethod;
}
*/
}
//2、call()方法
function extendsmethod2(){
function sayColor(sPrefix, sSuffix){
document.write(sPrefix + this.color +sSuffix);
}
var obj = new Object();
obj.color = "red";
sayColor.call(obj,"The color is ", ", a very nice color indeed.");//call第一个参数为传递给前面的sayColor方法中 this 的对象,后面为传递给sayColor的其他参数
//输出结果:The color is red, a very nice color indeed. 此例说明 call 方法的用法
//使用call方法继承
function ClassB(sColor, sName){
//this.newMethod = ClassA;
//this.newMethod(sColor);
//delete this.newMethod;
ClassA.call(this, sColor); //此方法代替上面3行的效果,ClassA定义同对象冒充方法
this.name = sName;
this.sayName = function(){
alert(this.name);
};
}
}
//3、apply()方法
function extendsmethod3(){
function sayColor(sPrefix, sSuffix){
document.write(sPrefix + this.color + sSuffix);
};
var obj = new Object();
obj.color = "red";
sayColor.apply(obj,new Array("The color is ",", a very nice color indeed.")); //apply()方法第一个参数仍为obj,即应该赋予sayColor()中的this关键字的值
//第二个参数是父类其他参数组成的数组。此例说明apply()方法的用法
function ClassB(sColor, sName){
//对象冒充的前三行由一行代替
ClassA.apply(this, new Array(sColor)); //另外可以用 ClassA.apply(this, arguments); 将ClassB的整个arguments对象作为第二个参数传递给apply()方法,需参数顺序一致
this.name = sName;
this.sayName = function(){
alert(this.name);
};
}
}
//4、原型链方法
function extendsmethod4(){
function ClassA(){
}
ClassA.prototype.color = "red";
ClassA.prototype.sayColor = function(){
alert(this.color);
};
function ClassB(){
}
ClassB.prototype = new ClassA(); //要确保ClassA的构造函数没有参数
ClassB.prototype.name = ""; //子类的所有属性和方法要在prototype属性被赋值之后
ClassB.prototype.sayName = function(){
alert(this.name);
};
//测试
var objA = new ClassA();
var objB = new ClassB();
objA.color = "red";
objB.color = "blue";
objB.name = "Nicholas";
objA.sayColor();
objB.sayColor();
objB.sayName();
//对ClassB的所有实例使用 instanceof 为ClassA和ClassB 都返回true
alert(objB instanceof ClassA);
alert(objB instanceof ClassB);
}
//5、混合方式,此方法为最好的继承方式
function extendsmethod5(){
function ClassA(sColor){
this.color = sColor;
}
ClassA.prototype.sayColor = function(){
alert(this.color);
};
function ClassB(sColor, sName){
ClassA.call(this, sColor); //用对象冒充继承ClassA类的sColor属性
this.name = sName;
}
ClassB.prototype = new ClassA(); //用原型链继承ClassA类的方法
ClassB.prototype.sayName = function(){
alert(this.name);
};
//测试
var objA = new ClassA("red");
var objB = new ClassB("blue", "Nicholas");
objA.sayColor();
objB.sayColor();
objB.sayName();
} 参考资料:JavaScript高级程序设计
转载于:https://www.cnblogs.com/leetom/archive/2010/10/24/2845905.html