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"と表示してほしかったところなのだけど、実行すると次の様に表示される。
f:id:hideack:20080317230534p:image
希望する動きにならない。次に次の様に書いてみる。

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();
}

こうすると実行結果は次の様になる。
f:id:hideack:20080317230457p:image
JavaScriptでは...

  • 関数はオブジェクト。メソッドは関数のオブジェクトが納められたもの。
    • なので先の前者の例では、引数で1つ与えられている方が引数無しの定義を上書きした(ってことでいいのかな...。)
    • そのため引数無しのメソッドを実行した場合、"50 + Nan = Nan"になった(で、いいんかいな。)
  • JavaScriptで関数が呼ばれた場合、引数がargumentsオブジェクトに自動的に格納される。
    • argumentsオブジェクトはlength, calleeプロパティを持つ。
      • lengthプロパティを使うことで引数別の切り分けができる。