(この回答は4年以上前のものです(2015年4月現在)。まだ正しいですが、より一般的な説明が必要だと思います-以下を参照してください)
元の答え
これについて考えてください:
(function (x) {
// ...
})(y);
なので:
function functionName(x) {
// ...
}
functionName(y);
ただし、名前を付ける必要はありません (functionName など)。
したがって、この:
(function(global) {
// ...
})(typeof window === 'undefined' ? this : window);
本当にただ:
function functionName(global) {
// ...
}
functionName(typeof window === 'undefined' ? this : window);
これは 1 つの引数 (global
関数内で呼び出される) を持つ関数でありtypeof window === 'undefined' ? this : window
、以下と同じ意味で呼び出されます。
function functionName(global) {
// ...
}
if (typeof window === 'undefined') {
functionName(this);
} else {
functionName(window);
}
ただし、短い表記を使用します (関数に名前を付けずに)。
より一般的な説明
私はこの回答を 4 年以上前に書きましたが、ここに含まれる概念の一般的な説明を追加する時が来たと思います。
上で説明したように、これは次のとおりです。
(function (x) {
// ...
})(y);
これの匿名バージョンです:
function functionName(x) {
// ...
}
functionName(y);
これは(一度だけ呼び出す場合)通常(例外については以下を参照)、これと同じです:
function functionName() {
var x = y;
// ...
}
functionName();
匿名の即時呼び出し関数に戻ると、次のようになります。
(function (x) {
// ...
})(y);
これと同じです:
(function () {
var x = y;
// ...
})();
これは、ほとんどの人にとってより明白な意味を持つ可能性があります。(ここで、すぐに呼び出される関数には引数がなく、変数やその他のネストされた関数に分離されたスコープを提供する目的のみに役立ちます。これにより、外側またはグローバル スコープを汚染しません。これは、引数を使用する主な理由でもあります。最初に無名関数をすぐに呼び出します。)
括弧について
ちなみにこれ:
(function () {
// ...
})();
これと同じです:
(function () {
// ...
}());
言語のあいまいさのために関数を囲む括弧が必要ですが、()
関数を実際に呼び出す が含まれている場合と含まれていない場合があります。詳細と、最初のバージョンが「犬のボール」のように見えると彼が考える理由については、Douglas Crockford によるこの説明を参照してください。
例外
以前、私はこう言いました。
(function (x) {
// ...
}(y));
これと同じです:
(function () {
var x = y;
// ...
}());
そして、これはほとんどの場合、1 つの引数に当てはまり (同時にその値に依存している間、外側のスコープで同じ名前の変数をマスクしません)、通常は複数の引数に当てはまります (そうでない場合)。 t も相互に依存します)。例でより明確になることを願っています。
このコードがある場合:
(function (x) {
// ...
}(x + 1));
次に、それを次のように翻訳することはできません。
(function () {
var x = x + 1;
// ...
}());
最初のバージョンでは、外部 に 1 を追加し、結果を内部x
にバインドし、関数の内部に入るとすぐに、内部のみを操作する必要があるためです(新しいステートメントでさえ、それには役立ちません)。 x
x
let
もう一つの例:
(function (x, outer_x) {
// ...
}(1, x));
ここでは、外側のスコープと内側のスコープの値を 1 の新しい値に設定できold_x
、x
順序x
を気にする必要はありません。しかし、あなたがした場合:
概要
ご覧のとおり、単純に翻訳できない状況がいくつかあります。
(function (x) {
// ...
}(y));
の中へ:
(function () {
var x = y;
// ...
}());
しかし、それが 2 番目の形式に翻訳できるのであれば、それは読みやすさのためであるべきだと私は主張します。特に大きな関数の場合、関数の先頭で使用されている変数の意味を知るために、関数の最後までスクロールする必要があるのは不便です。
質問に戻る
つまり、このコードを質問から翻訳します。
(function(global) {
var turing = {
VERSION: '0.0.1',
lesson: 'Part 1: Library Architecture'
};
if (global.turing) {
throw new Error('turing has already been defined');
} else {
global.turing = turing;
}
})(typeof window === 'undefined' ? this : window);
これに:
(function () {
var global = typeof window === 'undefined' ? this : window;
var turing = {
VERSION: '0.0.1',
lesson: 'Part 1: Library Architecture'
};
if (global.turing) {
throw new Error('turing has already been defined');
} else {
global.turing = turing;
}
}());
この回答で、これら2つが同等である理由が説明され、次のように記述できることを願っています。
(function (global, turing) {
if (global.turing) {
throw new Error('turing has already been defined');
} else {
global.turing = turing;
}
})(typeof window === 'undefined' ? this : window,
{VERSION: '0.0.1', lesson: 'Part 1: Library Architecture'});
それは同じことを意味しますが、同時に読みにくくなります。
同様の概念を説明している他の回答も参照してください。