JavaScript ほどの記述性の高さがあれば、実は new 演算子は要らないのではないか?
という疑惑を抱いて悶々としていたのが解決しました。
気になっていた
JavaScript: The Good Parts ―「良いパーツ」によるベストプラクティス
を入手してパラパラめくったら、信じられないことに「悪いパーツ」に
new 演算子が載っているではありませんか!
本書では new 演算子を使うべきでない理由を述べるとともに、関数型パターンによるアプローチを紹介しています。
ここでは気に入ったフレーズだけ引用しておきます(p.57)。
擬似クラス型のスタイルは、JavaScriptになじみのないプログラマに安心感を与えることができる。
しかし同時にこのスタイルは、JavaScriptの本質を隠してもしまう。
何故、このフレーズが気に入ったのか? それは「本質」という言葉が好きだからです :-)
疑惑の発端
1. new 演算子と apply メソッドは何が違うのだろう?
js> var foo = function(x,y){
this.add = function(){ return x + y; };
return this;
}
js> var bar1 = new foo(2,3);
js> var bar2 = new foo(4,5);
js> var qux1 = foo.apply({},[2,3]);
js> var qux2 = foo.apply({},[4,5]);
js> bar1.add();
5
js> bar2.add();
9
js> qux1.add();
5
js> qux2.add();
9
|
2. クロージャの存在 ☞ JavaScript とクロージャ
実験
冒頭の本に書かれている関数型パターンとは別に、
自分なりに new 演算子を使わないコードを書いてみました(実用性を求めない実験です)。
コードの概要は次の通りです。
- 擬似クラス型の雰囲気はそのままで、new 演算子の代わりに apply メソッドを使用する。
- 擬似クラス型のままで new 演算子を使わないということは、プロトタイプチェーン(__proto__)を自力で操作するということ。 これがどれ程のことなのか試してみる。
- プロトタイプチェーンを自力で操作するのであれば、prototypeプロパティは要らないのではないか。 試しに、独自に extプロパティを導入してみる。
ソースコード
nonew.js
#!/usr/local/bin/js
var foo = function(){ // 入出力器
var x, y;
this.set = function(a,b){ x = a; y = b; };
this.x = function(){ return x; };
this.y = function(){ return y; };
return this;
};
foo.ext = {
out: function(){
print('x=' + this.x() + ',y=' + this.y());
}
};
var bar = function(){ // 加減器
this.add = function(){ return this.x() + this.y(); };
return this;
};
bar.ext = {
sub: function(){ return this.x() - this.y(); }
};
var qux = function(){ // 乗除器
this.mul = function(){ return this.x() * this.y(); };
return this;
};
qux.ext = {
div: function(){ return this.x() / this.y(); }
};
var obj = (function(){ // 組み立て
var that = {};
foo.apply(that) .__proto__ = foo.ext; // foo.ext をチェーンの先頭へ
bar.apply(foo.ext).__proto__ = bar.ext; // bar.ext をチェーンの中央へ
qux.apply(bar.ext).__proto__ = qux.ext; // qux.ext をチェーンの後尾へ
return that;
})();
obj.set(20,5); // 試運転
obj.out();
print("x+y=" + obj.add());
print("x-y=" + obj.sub());
print("x*y=" + obj.mul());
print("x/y=" + obj.div());
|
実行結果
$ chmod +x nonew.js
$ ./nonew.js
x=20,y=5
x+y=25
x-y=15
x*y=100
x/y=4
|
覚え書き
実験を終えて
- ほとんどブラックボックスが無いので見通しが良い。
- __proto__ がゴツい。 ついでに、IE では使えない。
- どんな穴(問題)があるのか想像できない。
- 価値のあるパターンを生み出すのは大変なことだ。
更新履歴
| 日付 |
内容 |
| 2009-12-29 |
追加 |
セクション「関連リンク」 |
| 2009-02-26 |
追加 |
セクション「疑惑の発端」 |
| 2009-02-24 |
追加 |
セクション「実験」「覚え書き」 |
| 2009-02-13 |
初版 |
|