2010年01月26日

javascript:「new」そんなに嫌わないで・・・

前の「javascript:クラス風の定義をしないメソッドチェーンです」で、new なんて・・・。とか言いながら下記の記事を見つけたので、天の邪鬼に走った思考がムクムク。と。

あと味さん
JavaScriptのnewって本当にいらない子?
http://d.hatena.ne.jp/jdg/20090706/1246840565

function f(){}
f.prototype.m = function (){
  alert(this == window);
}; //「;」は略せない! 試すと分かるけど下の結果が変わる。よく抜けてしまうけどw

(new f()).m(); // false





自分も new は、使わなくても良いってスタンスですが、いらない子扱いは可哀そうじゃないかなぁ。Javascript の場合、コンストラクタに色々処理を記述してしまう設計自体がクラス寄りの思考であって、new が悪い訳じゃない。つまり、クラスベースの思想をそのまんま持ち込むコードの書き方の方が悪い。つまり・・・。

> newを付けるべきところに付けないまま実行

ってのは「newを付けるべきところ」ってのがミソじゃないかな。new を付けるべきところって何? new 悪い奴って書いてある本を読んだ事ないので知らないけど、それってクラスベース風にコンストラクタにガリガリ処理を書いたところじゃない? new が悪いのとは、実は全然話が違う。new を付けないまま実行させられない所を作ってしまう事自体が問題なんじゃないかな。つまり new 以前の問題では? ま、あくまで new 排斥意見(汗)の論拠に立脚した見解で。自分はそんな事気にしないw

例えば、オブジェクトを直に記述し、オブジェクトをつなげてゆくというスタンスでは、コンストラクタなんて実質不在ですよね。例をあげると下のような感じ、

o = {
  p : 1,
  m : function (){処理}
};
alert(o.constructor); // Object

当然 class ベースでのユーザ定義クラスのコンストラクタは不在。

ならば、javascript にクラスベースを持ち込む場合、オブジェクトであるという事を認識して、クラス定義相当のコンストラクタは無視した方がいい。コンストラクタは、あくまで ptrototype を準備させるだけの関数オブジェクトと割り切れば、javascript の作法(設計思想?)に則ったクラス設計になるんじゃないかな。つまり、一番上の様にしょっぱなの関数内には何も書かない。

まあ、object 関数使ってオブジェクト取り回せばクラスベースに寄った思考回路が壊れて新しい道を見つけるので、すごく良いんだろうけど(自分もそのクチ)。ただ new は new で時と場合に応じて使って行けばいい。特に多言語開発では、javascript はプロトタイプベースだから!なんて意地張ったって、ただの痛い子だしw それなら他の言語に慣れた人の回路も使ってサービスを向上させる議論にエネルギーを注いだ方がいいと思う。もちろん、別手法の勉強をしてもらう機会も設ければいい訳だし。

ちなみに、あと味さんの ex10 はプロトタイプが Object.prototype に繋がっている。object ではなく Object。紛らわしいのでコード書き換えます。

var Blog = function() {
  var o = {};
  return o;
};
Object.prototype.title = 'あと味';
Object.prototype.author = 'jdg';

var blog = Blog();
alert(blog.title + ' writen by ' + blog.author); // あと味 writen by jdg

とするとチェーンが繋がる。ただ、これをやると以後すべてのオブジェクトに影響してしまうので、時として非常に嫌われる。(自分も苦手)
※ 下記コード試す場合は、上記コードを消してください。

おまけ。
関数内に this があり、new 使わなくても window を汚染しない関数。
ま、知ってる人は当たり前だけど。

function f(){
  if(this == window) return f.apply({}, arguments);
  this.contami = '汚染';
  return this;
}

o = f();
alert(o.contami); // 汚染
alert(window.contami); // undefined

window 汚染されていない。ただし f.prototype.うんぬんやっても prototype は解決されません。

あと味さんの ex10。
object 関数内で new を許容するなら、Blog 関数内でも new を許容すれば定義外で new を使わないコーディングも・・・。クラスにしろ関数にしろ設計者は、どこに new を使うべきか分かっている。けど、利用側が分かっていなくとも OK にするという思想なら

var Blog = function() {
  if(this == window) return new Blog();
  return this;
};
Blog.prototype = {
title : 'あと味',
author : 'jdg'
};

var blog = Blog();
alert(blog.title + ' writen by ' + blog.author); // あと味 writen by jdg
alert(window.title); // undefined
posted by HiFa at 04:32 | 🌁 | Comment(0) | TrackBack(0) | JavaScript雑感 | このブログの読者になる | 更新情報をチェックする
>>> スパムコメントは消してますよん。 お互い無駄な労力は避けましょう。 <<<

この記事へのコメント

コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
この記事へのトラックバックURL
http://blog.seesaa.jp/tb/139377003
※言及リンクのないトラックバックは受信されません。

この記事へのトラックバック
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。