[1] 对象伪装法 (Object Masquerading)
对象伪装法实际是程序员为了实现继承的 Trick
继承:ClassB 继承 ClassA,注意 delete this.newMethod 的使用。
![程序代码](http://cz9908.w6.vshow.cn/blog/images/code.gif)
function ClassA(sColor) {
this.color = sColor;
this.sayColor = function(){
alert(this.color);
}
}
/* ClassB 的原始定义 */
function ClassB(sColor) {}
/* ClassB 定义2 */
function ClassB(sColor) {
this.newMethod = ClassA;
this.newMethod(sColor);
delete this.newMethod; //删除对ClassA的引用,避免以后被调用
}
/* ClassB 定义3 */
function ClassB(sColor, sName) {
this.newMethod = ClassA;
this.newMethod(sColor);
delete this.newMethod;
this.name = sName;
this.sayName = function() {
alert(this.name);
}
}
[2] 多重继承
ClassZ继承自ClassX与ClassY
![程序代码](http://cz9908.w6.vshow.cn/blog/images/code.gif)
this.newMethod = ClassX;
this.newMethod();
delete this.newMethod;
this.newMethod = ClassY;
this.newMethod();
delete this.newMethod;
}
上述的实现有一个Gotcha,当ClassX与ClassY有同名的属性或方法时,因为ClassY后初始化,所以会覆盖掉ClassX的同名方法或属性。
[3] 使用call()方法实现
call()方法的第一参数为被当作This的对象,其他参数直接被传给funciton,通过使用Call(),我们也可以实现继承:
![程序代码](http://cz9908.w6.vshow.cn/blog/images/code.gif)
ClassA.call(this, sColor);
this.name = sName;
this.sayName = function() {
alert(this.name);
}
}
[4] 使用Apply()方法实现
Apply()方法只有两个参数,第一个与call()一样,被当作this;第二个是被传入function的参数数组,使用Apply()的好处是你可以使用function的arguments对象直接当作第二参数。
![程序代码](http://cz9908.w6.vshow.cn/blog/images/code.gif)
ClassA.apply(this, arguments); // 注:参数的顺序必须和ClassA定义的顺序一致
this.name = sName;
this.sayName = function() {
alert(this.name);
}
}
注意:如果使用arguments对象则需保证参数顺序与ClassA一致。
[5] 使用Prototype链
要求构造器不能有参数
![程序代码](http://cz9908.w6.vshow.cn/blog/images/code.gif)
ClassA.prototype.color = "red";
ClassA.prototype.sayColor = function() {
alert(this.color);
}
function ClassB(){}
ClassB.prototype = new ClassA();
ClassB.prototype.name = "";
ClassB.prototype.sayName = function() {
alert(this.name);
}
好处是可以使用instanceof,对对象进行判断,如果obj为ClassB对象,则instanceof ClassA和ClassB都会为true,这是使用伪装法所不具备的,但是prototype的构造器不能有参数。所以 最好的方式是混合法。
[6] 使用混合法
![程序代码](http://cz9908.w6.vshow.cn/blog/images/code.gif)
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);
}
但是混合法的缺点是无法多重继承。
[7] 动态原形法的一些问题
主要指xxx.protoype = new xxx() 不能被放在构造器里面,必须放在外面,可是如果要放在外面,那动态原形法本身就失去意义了,因为动态原形法本身就是为了把原形方法放在function的构造器里面,以使得代码风格接近Java。所以最好还是不要用动态原形法了。
[8] 利用其它通过工具库实现继承
xbObject(http://archive.bclary.com/xbProjects/)
Zinherit (Nicholas C. Zakas的库,Professional Javascript for web developer的作者)