javascriptでスーパークラスのメソッドを簡単に呼び出したかった。それだけだった。
var Class = inherit(SuperClass,{hoge: ...});
作ったクラスはprototypeに、第二引数のオブジェクトがコピーされたスーパークラスのインスタンスを持つ。
第一引数がnullだと、スーパークラスにObjectを用いる。つまり、
var Class = inherit(null,{hoge: ...});
は
var Class = inherit(Object,{hoge: ...});
と同等となる。
また、第一引数が"prototype"をメンバに持たない普通のオブジェクト、つまり、
var Class = inherit({hoge: ...});
だと
var Class = inherit(Object,{hoge: ...});
と同等となる。
var obj =new Class({hoge: ...});
でインスタンスを作ると、引数のオブジェクトのコピーを持つオブジェクトとなる。
また、メソッド"initialize"が自動的に実行される。
ただし、コンストラクタに引数を渡さなかった場合は、initializeは実行されない。
this.superapply(arguments);
としてスーパークラスのメソッドを呼べる。第一引数は呼び出すメソッドの引数の配列とする。
このとき、呼び出し側のメソッドはコンストラクタやinheritでオーバーライドしたメソッドでなくてはならない。これは呼び出し側のメソッド名を記録する必要があるためである。
そうでない場合は第二引数にメソッド名を渡す必要がある。
var obj =new Class({});obj.foo =function(){this.superapply(arguments);// Xthis.superapply(arguments,"foo");// O};
<html><head><script type="text/javascript">function inherit(superclass, override){if (!superclass)superclass =Object;if (!"prototype" in superclass){override = superclass;superclass =Object;}var that;var func;function superapply(arg,name){var prev ={that: that, func: func};try{var my =this.superapply;if (!arg)arg = [];if (!name)name = arguments.callee.caller.caller.methodName;if (that && func && (!name ||name == func.methodName)){that = that.superapply.obj;name = func.methodName;}elseif (name){that = my.obj;func = arguments.callee.caller.caller;func.methodName =name;}else{thrownew Error("methodName is null");}var result;if (func === that[name]){result =this.superapply(arg,name);}else{func = that[name];func.methodName =name;result = func.apply(this, arg);}} finally{that = prev.that;func = prev.func;}return result;};varprototype =new superclass();prototype.superapply =function(){superapply.apply(this, arguments)};prototype.superapply.obj = superclass.prototype;if (override)for (var i in override){prototype[i] = override[i];if (typeof override[i] =="function")prototype[i].methodName = i;}var subclass =function(obj){this.superapply =function(){superapply.apply(this, arguments)};this.superapply.obj =prototype;if (obj){for (var i in obj){this[i] = obj[i];if (typeof obj[i] =="function")this[i].methodName = i;}this.initialize();}};subclass.prototype =prototype;subclass.prototype.constructor = subclass;return subclass;}var C1 = inherit(Object,{fn:"C1",initialize:function(){alert("C1.initialize");this.second(this.fn);},second:function(a){alert("C1.second: "+a);}});var C2 = inherit(C1,{fn:"C2",initialize:function(){alert("C2.initialize");this.superapply();//},//second://function(a){//alert("C2.second: "+a);//this.superapply([a]);}});varC3 =new C2({fn:"C3",//initialize://function(){//alert("C3.initialize");//this.superapply();//},second:function(a){alert("C3.second: "+a);this.superapply([a]);}});</script></head><body></body><html>
methodNameなんとかならんもんか。