JavaScriptでオーバーロード
うーん。修行不足を実感。
prototype.jsを使ってJavaScriptで下の様な感じのプログラムを書いてしまった。
var Car = Class.create(); Car.prototype = { initialize : function(){ this.oil = 50; }, chargeOil : function(){ this.oil += 50; }, chargeOil : function(order){ this.oil += order; }, showStatus : function(){ alert("Oil=" + this.oil); } }; window.onload = function() { mycar = new Car(); mycar.chargeOil(); mycar.showStatus(); }
Java等々の言い方で言うとchageOilメソッドをオーバーロードの乗りで実装してしまったという訳。
これを実行したとき、頭では"100"と表示してほしかったところなのだけど、実行すると次の様に表示される。
希望する動きにならない。次に次の様に書いてみる。
var Car = Class.create(); Car.prototype = { initialize : function(){ this.oil = 50; }, chargeOil : function(order){ if(arguments.length == 0){ this.oil += 50; } else if(arguments.length == 1){ this.oil += order; } }, showStatus : function(){ alert("Oil=" + this.oil); } }; window.onload = function() { mycar = new Car(); mycar.chargeOil(); mycar.showStatus(); }
こうすると実行結果は次の様になる。
JavaScriptでは...
- 関数はオブジェクト。メソッドは関数のオブジェクトが納められたもの。
- なので先の前者の例では、引数で1つ与えられている方が引数無しの定義を上書きした(ってことでいいのかな...。)
- そのため引数無しのメソッドを実行した場合、"50 + Nan = Nan"になった(で、いいんかいな。)
- JavaScriptで関数が呼ばれた場合、引数がargumentsオブジェクトに自動的に格納される。
- argumentsオブジェクトはlength, calleeプロパティを持つ。
- lengthプロパティを使うことで引数別の切り分けができる。
- argumentsオブジェクトはlength, calleeプロパティを持つ。