JavaScriptでnewを忘れるとグローバル変数を上書きしてしまう

はてなブックマークに追加はてなブックマーク Yahoo!ブックマークに登録 ニフティクリップに追加 Livedoor クリップに追加 BuzzurlにブックマークBuzzurlにブックマーク Twitterに投稿  

JavaScriptでnewを忘れるとグローバル変数を上書きしちゃうので、ちょっと危険だという記事を読みました。

JavaScriptのnew - watawata日記
function User(first, last){
    this.name = first + " " + last;
}
var user = new User("John", "Resig");
user.name // "John Resig" 

しかしこの方法だとnewを忘れた場合に問題があります。thisにグローバルオブジェクトがセットされるためグローバル変数を上書きしてしまいます。

興味深かったとともに、jqueryでのmakeClass()の実装が、よく抜け道突いてるなぁ、と感心しました。
jqueryのmakeClass()は、newなしで呼ばれると、実際には2回呼ばれることになるそうなのですが、分かりやすく実感するために、以下のようにコードを書き加えてみました。

function makeClass(){
  return function(args){
    if ( this instanceof arguments.callee ) {
      document.write("if true:<br>" + this + "<br>" + arguments.callee.caller + "<br>");
      if ( typeof this.init == "function" )
        this.init.apply( this, args.callee ? args : arguments );
    } else {
      document.write("else:<br>" + this + "<br>" + arguments.callee.caller + "<br>");
      return new arguments.callee( arguments );
    }
  };
}
 
var User = makeClass();
User.prototype.init = function(first, last){
  this.name = first + " " + last;
};
var user = User("John", "Resig");
user.name // => "John Resig"

これで実行したところ・・・

else:
[object Window]
null
if true:
[object Object]
function (args) { if (this instanceof arguments.callee) { document.write("if true:
" + this + "
" + arguments.callee.caller + "
"); if (typeof this.init == "function") { this.init.apply(this, args.callee ? args : arguments); } } else { document.write("else:
" + this + "
" + arguments.callee.caller + "
"); return new (arguments.callee)(arguments); } }

と出力され、まず1回目にelse節が呼ばれた後、if文がtrueと評価されて呼び出されていることを確認できる。
また、this と arguments.callee.caller も、1回目と2回目で違うことを確認できる。


日時: 2009年06月17日 11:03
コメントを投稿






トラックバック

■この記事のトラックバックURL:
http://www.mapee.jp/mpe334/mt-tb.cgi/485

この記事にトラックバックされる方は、参照先が分かるようにするために、「JavaScriptでnewを忘れるとグローバル変数を上書きしてしまう」へのリンクをお願いいたします。
以下のHTMLタグをトラックバック送信元ページ内に挿入して下さい。



※この記事へのリンクがない、また関連のないページからのトラックバックは反映されませんので、ご了承下さい。






あわせて読みたいブログパーツ
フィードメーター - ウェブライフハック