研究javascript是很有意思的事情,以前我说过,在javascript中的继承,在于维持prototype指向同一object就行了,确实这样。
我今天做的尝试是,如何更它更像其他的语言一样的使用继承机制,多层继承和更方面的调用父类的构造。
我希望达到的效果:
function A(){ alert('a'); } function B(){ this.$supClass(); alert('b'); } extend(B,A); function C(){ this.$supClass(); alert('c'); } extend(C,B); var c = new C(); alert( c instanceof A ); // true alert( c instanceof B ); // true alert( c instanceof C ); // true
实例:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title> js继承 </title> </head> <body> </body> </html>我的extend是这样写的:
1 function extend(subClass,supClass){ 2 var fun = function(){}, 3 prototype = subClass.prototype; 4 fun.prototype = supClass.prototype; 5 subClass.prototype = new fun(); 6 for( var i in prototype){ 7 subClass.prototype[i] = prototype[i]; 8 } 9 subClass.$supClass = supClass; 10 subClass.prototype.$supClass = function(){ 11 var supClass = arguments.callee.caller.$supClass; 12 if( typeof supClass == 'function'){ 13 supClass.apply( this,arguments); 14 this.$supClass = supClass; 15 } 16 }; 17 subClass.prototype.constructor = subClass; 18 return subClass; 19 }
也许你会问,为什么不这样写:
function extend(subClass,supClass){ var fun = function(){}, prototype = subClass.prototype; fun.prototype = supClass.prototype; subClass.prototype = new fun(); for( var i in prototype){ subClass.prototype[i] = prototype[i]; } subClass.prototype.$supClass = function(){ supClass.apply( this,arguments); }; subClass.prototype.constructor = subClass; return subClass; }
这样看似没有问题,只有一级继承时会运行的很好,但是,如果多级继承时,就会造成死循环,因为:
subClass.prototype.$supClass = function(){ supClass.apply( this,arguments); };
这个方法会被一直覆盖重写掉,而造成死循环。
而我的做法是,用类的$supClass属性指向它所继承的父类构造,在prototype中也有个$supClass方法,这个$supClass第一次必须要在类的构造器中执行,prototype.$supClass在执行时,会通过arguments.callee.caller.$supClass来获得类的$supClass,然后通过apply在this执行。 这样$subClass就能根据不同的来,来获得类的父类构造器并执行。