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プロパティを使うことで引数別の切り分けができる。