5

underscore.js ライブラリ(jQuery は同じことを行います)のコードを見ていて、ウィンドウ オブジェクトが自己実行関数に渡される理由を明確にしたかっただけです。

例えば:

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

グローバルなのでthis、なぜ関数に渡されるのですか? 以下も同様に機能しませんか?このようにすると、どのような問題が発生しますか?

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

2 に答える 2

5

その理由は ECMAScript 5 strict modeにあると思われます。

非厳密モードでは、この IIFE

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

グローバルオブジェクトは、オブジェクトのメソッドとして実行されない関数として提供されるため、windowオブジェクト (またはglobalnode.js サーバー上にいる場合はオブジェクト) をログに記録します。this

その結果を比較してください

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

厳密モードでは、そのままthis呼び出された関数の は未定義です。したがって、Underscore の作成者は、厳密モードと非厳密モードで標準化されるように、無名関数にcall明示的に指定するために使用します。this単純に関数を呼び出したり (私の例で行ったように) 使用したりする.call()と、 で解決できる矛盾が生じ.call(this)ます。

于 2012-12-13T18:15:55.633 に答える
1

jQuery も同じことを行います。SO に関する質問に対するいくつかの回答は、それらの行に沿って検索することで見つけることができます。

ローカル スコープのように常に使用可能なグローバル変数を使用する理由は 2 つありますwindow。どちらもかなりマイナーな最適化のためです。

  1. 読み込み時間。インタープリターはコンテキスト ツリーを調べる必要がないため、ローカル変数の検索はグローバル変数の検索よりも少し時間がかかります。関数の長さは、アンダースコアまたは jQuery のサイズであり、理論的には、低速のマシンではそれほど重要ではありません。

  2. ファイルサイズ。Javascript の縮小は、変数が一貫している限り、変数に任意の名前を付けることができるという事実に依存しています。縮小版にmyLongVariableNameなります。aもちろん、問題は、これがスクリプト内で定義された変数にしか適用できないことです。外部から取得するものはすべて、機能するために同じ名前を保持する必要windowprあります。それ自体への参照でシャドウすることにより、Minify は次のようなことができます。

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

    そうでなければwindow(6 文字) を入力するたびに、A(1 文字) になります。繰り返しますが、メジャーではありませんが、スコープ管理のために定期的に明示的に呼び出す必要がある大きなファイルではwindow重要になる可能性があり、2 回使用すると、すでに数文字の利点があります。また、限られたサーバーでサービスを提供する大規模で人気のあるライブラリや、お粗末なインターネット プランを使用している可能性のある人々にとっては、すべてのバイトが重要です。


質問に関するコメントを読んだ後に編集します。

実際にfunction.call()を行うかを見ると、2 番目のスニペットは実際にthisは機能しません。渡されるのは引数ではなく、関数の明示的な呼び出しコンテキストであり、それを に提供する必要があります.call()。ファイルの先頭にある行は、上記の 2 つの目的に役立ちます。でコンテキストを明示的に設定する理由は、将来を保証するためです。call現時点では、無名関数はグローバル コンテキストを取得しますが、理論的には、これが変更されたり、将来の ECMA 仕様で推奨されなくなったり、ニッチなブラウザーで奇妙な動作をする可能性があります。インターネットの半分が使用するものについては、より明確に説明し、問題を完全に回避することが最善です。this/ _windowトップレベルでの選択は、PC 以外のデバイス (つまりモバイル) がトップレベル オブジェクトに別の名前を使用している可能性があることを心配することと関係があるに違いないと思います。

于 2012-12-13T18:09:31.747 に答える