オブジェクト指向っぽい

先日AJAXっぽいことをしたが、Javascriptの部分が行きあたりばったりでベタに書いてしまっていたんで、改良を加えつつ整理した。そのときに調べたJavascriptのオプジェクト指向なあたりをメモ。
Javascriptオブジェクト指向ではないものの、型宣言をしなくていい弱い型付けの言語であり、関数オブジェクトが内部変数を保持できる*1ので、その内部変数に関数を突っ込むとメソッドっぽく扱える。

var test = new Test();
alert(test.get()); /* 0 */
test.set(4);
alert(test.test(100)); /* 104 */

function Test() {
  this.value = 0;
  this.get = function () {
    return this.value;
  }
  this.set = function (arg) {
    this.value = arg;
  }
  this.test = function (arg) {
    return arg + (this.get());
  }
  return this;
}

こんなんができるかな?valueがフィールド、getとsetがvalueに対するアクセッサ。でもオブジェクト毎のprivateな変数は扱えない*2らしいんで、getとsetを作る意味はない。そもそも型付けが弱いし。

Javascriptは関数型の言語に結構近いんやが、関数呼出しが2,3重くらいならええんやが数字が大きくなってくるとすぐバッファが溢れてエラーになるんが微妙なところ。

例えば、

function sum(x) {
  if(x <= 1)
    return 1;
  else
    return x + sum(x-1);
}

でやってみた。Firefoxではきっかり1000までしか動かんかった。それ以上やるとJavascriptコンソールにtoo much recursionとか出る。IEでは1119まで動いて、それ以上になるとStack overflowとか出てIEを再起動するまでJScriptが死にっぱなしになる。このへんの仕様は腐ってるなぁIE

まぁそんな感じで再帰的な手法があんまり使えんから、大体オブジェクト指向っぽい方向でプログラムを組むわけやな。きっと。

function Super(){
  this.method1 = function () { ... }
}
function Sub(){
  this.method2 = function () { ... }
}
Sub.prototype = new Super;

とかやって継承もできるらしい。

*1:所謂Closureが使える

*2:ローカルな変数としてはvarによる変数定義でできるんやが、これはクラスで共用の、staticなスコープになるらしい。このへんで規模が大きくなるとソースがスパゲッティになる予感がしてくるわけだ。