6
var module = {};


(function(exports){

  exports.notGlobalFunction = function() {
    console.log('I am not global');
  };  

}(module));

function notGlobalFunction() {
  console.log('I am global');
}

notGlobalFunction(); //outputs "I am global"
module.notGlobalFunction(); //outputs "I am not global"

誰かが私がここで何が起こっているのかを理解するのを手伝ってもらえますか?をnotGlobalFunction()呼び出すと、2番目の関数が呼び出されるだけです。

しかし、何をしているのvar module = {}でしょうか?そして、なぜそれが最初の関数内で再び呼び出されるのですか?

これは一般に自己実行型の無名関数として知られていると言われていますが、それが何を意味するのかはよくわかりません。

4

4 に答える 4

25

即時呼び出し関数は通常、プライベートで外部からアクセスできないローカル関数スコープを作成するために使用され、外部に影響を与えることなく独自のローカルシンボルを定義できます。多くの場合、これは良い習慣ですが、この特定のケースでは、何にも使用されていないため、数行のコード以外の利点が得られるとは思いません。

このコード:

(function(exports){

  exports.notGlobalFunction = function() {
    console.log('I am not global');
  };  

}(module));

次のような即時呼び出しがないコードと同じになります。

module.notGlobalFunction = function() {
   console.log('I am not global');
};  

異なる点の1つは、最初に、すぐに呼び出される関数ブロックに対してローカルであるmodulescalledのエイリアスが作成されることです。exportsただし、エイリアスでは一意の処理は行われず、コードをmodules直接使用することもできます。


変数modulesは、他の多くのグローバル変数をプロパティとして保持できる単一のグローバル親オブジェクトとして作成されます。これはしばしば「名前空間」と呼ばれます。これは、同じプロジェクト/ページで使用される他のコードと競合する可能性のあるトップレベルのグローバル変数の数を最小限に抑えるため、一般的に優れたデザインパターンです。

したがって、次のように複数のトップレベル変数を作成するのではなく、次のようにします。

var x, y, z;

次のような単一のトップレベル変数を作成できます。

var modules = {};

次に、他のすべてのグローバルをプロパティとしてアタッチします。

modules.x = 5;
modules.y = 10;
modules.z = 0;

このように、まだ複数のグローバル変数がありますが、他のコードと競合する可能性のあるトップレベルのグローバルは1つだけです。


同様に、即時呼び出し関数は、ローカルのプライベートスコープを作成します。このスコープでは、そのスコープに対してローカルであり、他のコードに干渉しない変数を作成できます。

(function() {
    var x, y, z;

    // variables x, y and z are available to any code inside this immediately invoked function
    // and they act like global variables inside this function block and
    // there values will persist for the lifetime of the program
    // But, they are not truly global and will not interfere with any other global
    // variables and cannot be accessed by code outside this block.
    // They create both privacy and isolation, yet work just as well


})();

すぐに呼び出される関数に引数を渡すことは、それ自体のローカルシンボルを持つすぐに呼び出される関数のスコープに値を渡す方法にすぎません。

(function(exports) {
    // creates a local symbol in this function block called exports
    // that is assigned an initial value of module
})(module);
于 2013-01-14T16:48:55.967 に答える
2

これにより、新しい空のオブジェクトが作成されます。

var module = {};

それは同じことをします:

var module = new Object();

このラッパー:

(function(exports){
  ...
}(module));

関数内に変数のエイリアスを追加することのみを実行しmoduleます。その無名関数内にはローカル変数や関数がないため、それがなくても同じことができます。

module.notGlobalFunction = function() {
  console.log('I am not global');
};  

このような無名関数は、たとえば、プライベート変数を作成するために使用できます。

(function(exports){

  var s = 'I am not global';

  exports.notGlobalFunction = function() {
    console.log(s);
  };  

}(module));

これで、オブジェクトnotGlobalFunctionに追加されたメソッドは変数にアクセスできますが、他のコードは変数にアクセスできません。modules

于 2013-01-14T16:48:36.607 に答える
0

「自己実行」は誤解を招く可能性があります。これは無名関数式であり、何かへの引数として割り当てられたり、与えられたりすることはありませんが、呼び出されます。即時呼び出し関数式(IIFE)についてはこちらをお読みください。

var module = {}は何をしていますか?

名前空間として機能している空のオブジェクトを初期化します。

なぜfist関数内で再び呼び出されるのですか?

これは「呼び出される」ものではなく、最初の関数の「内部」でもありません。オブジェクトはIEFEへの引数(「エクスポート」)として与えられ、その中にプロパティが割り当てられています。

于 2013-01-14T16:51:06.707 に答える
0

IIFEはmodule、パラメーターとして渡されるオブジェクトにメソッドを追加しています。コードは、関数がスコープを作成することを示しています。ブラウザのオブジェクトとヘッドオブジェクト(ウィンドウ)に同じ名前のメソッドが追加されています。

于 2013-01-14T16:52:55.517 に答える