あと味さん
JavaScriptのnewって本当にいらない子?
http://d.hatena.ne.jp/jdg/20090706/1246840565
function f(){}
f.prototype.m = function (){
alert(this == window);
}; //「;」は略せない! 試すと分かるけど下の結果が変わる。よく抜けてしまうけどw
(new f()).m(); // false
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
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
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
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
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
この記事へのコメント