5

私はunderscore.js library(jQueryは同じことをしています)のコードを見ていて、なぜウィンドウオブジェクトが自己実行機能に渡されているのかを明確にしたかっただけです。例えば変数がグローバルである場合、なぜjavascriptの自己実行関数に引数を渡す必要がありますか?

:それは関数に渡されている理由this以来

(function() {   //Line 6 
    var root = this;  //Line 12 
    //Bunch of code 
}).call(this);   //Very Bottom 

は、世界的なのですか?次のような仕事もないでしょうか?このようにしてどのような問題が発生するのでしょうか?

(function() { 
    var root = this; 
    //Bunch of code 
}).call(); 
+0

明らかに同じですが、どこにアンダースコアのjsコードを投稿できますか? – jxs

+0

引数は渡されません。コールバック内で 'this'を設定するために' call'が使用されています。それでも、なぜあなたが投稿したコードからのみこれが必要であるかわかりません。 – apsillers

+0

この関数は6行目から始まり、12行目で変数のルートがデカールされ、呼び出しは最後にあります。ファイル全体が一つの大きな機能です。 – KingKongFrog

答えて

4

理由はECMAScript 5 strict modeと思われます。 (あなたはNode.jsのサーバーにしている場合、またはglobalオブジェクト)グローバルオブジェクトはthisへと供給されているので、非strictモードで

、この生命維持

(function() { 
    console.log(this); // window or global 
})(); 

は、windowオブジェクトをログに記録しますオブジェクトのメソッドとして実行されない関数。

が厳密モードで

"use strict"; 
(function() { 
    console.log(this); // undefined 
})(); 

にその結果を比較し、裸呼び出される関数のthisは未定義です。したがって、アンダースコアの作成者は、callを使用して、匿名関数に明示的にthisを指定し、厳密および非厳密モードで標準化されるようにします。関数を呼び出すだけで(例のように)、または.call()を使用すると、.call(this)で解決できる矛盾が生じます。

1

jQueryのは、同じことをして、あなたはそれらの線に沿って検索することにより、SO上のあなたの質問にいくつか答えを見つけることができます。

  1. ロード時間:

    はかなりマイナーな最適化のためにあるどちらもローカルスコープでwindowのような常時使用可能なグローバル変数を持ってするには、2つの理由があります。インタプリタは文脈ツリーを遠くまで見る必要がないので、ローカル変数を調べることは、グローバル変数を探すよりもわずかな時間がかかります。 UnderscoreまたはjQueryのサイズの関数の長さに渡って、理論的には遅いマシンではあまり重要ではない時間を追加することができます。

  2. ファイルサイズ。 Javascriptの縮小は、一貫している限り、変数の名前を付けられるという事実に依存しています。 myLongVariableNameは、aになります。キャッチは、もちろん、スクリプト内で定義された変数にのみ適用できます。 windowprに縮めれば、あなたが話していることを通訳者は知りません。なぜなら、外部から引っ張っているものは同じ名前をつけなければならないからです。自分自身を参照して、それをシャドーイングすることにより、縮小化は、のようなものを行うことができます:あなたはそれ以外の場合はwindow(6文字)を入れているだろう

    (function(A){ B(A, {...}); A.doStuff(); //etc });})(window) 
    

    とするたびに、あなたは今A(1文字)を持っています。繰り返しますが、メジャーではありませんが、スコープ管理のために定期的にwindowを明示的に呼び出す必要がある大きなファイルでは、重要になる場合があります。また、2回使用すると、また、限られたサーバーと、インターネットプランが貧弱な人たちにサービスを提供する大規模な一般的なライブラリでは、すべてのバイト数が重要です。


編集質問にコメントを読んだ後:あなたはwhat function.call() actually doesを見れば、あなたの第二のスニペットが実際に動作しないでしょう

- thisが渡されて、それが明示的だ、引数ではありません関数のコンテキストを呼び出すと、.call()に渡す必要があります。ファイルの先頭の行は上記の2つの目的を果たします。コンテキストを明示的にcallに設定する理由は未来のものです。現在、匿名関数はグローバルコンテキストを取得しますが、理論的には将来変更される可能性があり、将来のECMA仕様では落胆したり、ニッチブラウザでは不思議です。インターネットの半分が使用するものについては、より明示的に問題を完全に回避することが最善です。 this/windowトップレベルでの選択トップレベルのオブジェクトに別の名前を使用する可能性のある非PCデバイス(モバイルなど)について心配する必要があると思います。

関連する問題