すぐに呼び出された関数式を理解する
9487 ワード
すぐに呼び出された関数式-しばしばiifeに省略され、' iffy '発音- JavaScriptで非常に強力で便利な構成です.
おそらく次のようになります.
いくつかの基本的な概念を経て、JSエンジンがどのようにこのコードブロックを解析するかを理解しましょう.
文対式
まず、文と表現の違いを理解することが大切です.
ステートメントは、単にいくつかのタイプの作業を行う実行のスタンドアローンユニットです.簡単な例は
対照的に、式はいくつかのタイプの仕事も実行することができる実行の単位です、そして、それから値に下げられます(または評価されます).例えば、式
JSでは、関数は文か式のどちらかであるので、これは重要です.関数文は以下のようになります:
一方、関数式は次のようになります.
「オブジェクト」という単語の使用によって混乱するかもしれません.本当に、JSでは、関数は実際にオブジェクトの特別なタイプです.関数オブジェクトには
即時関数実行
関数式を実行するのは、変数への代入後に行う必要はありません.これを評価する式の直後にペアのペアを追加し、その直後に実行します.
その理由を理解するには、operator precedence table on MDN .
この表は、演算子が評価される順序を示します.'優先度'列でより高い数の演算子は、より低い数のものの前に評価されます.
代入演算子の優先順位を探す場合
したがって、エンジンがスニペットを解釈する順序は以下の通りです.
メモリのアドレスを名前で割り当てる
2)関数オブジェクトを作成する関数式を評価します.
3 )関数を実行します.関数は明示的な返り値を持たないので、この式は
4 )最後の評価結果を変数に代入する
当然のことながら、関数が明示的な戻り値を持っていたなら、変数に代入します.
単独表現
JSエンジンはどこにも使われない無駄な表現を解釈することを気にしません.
それはちょうど声明と言います?
実際、関数文と関数式の違いは、キーワード
代入演算子のオペランドとして関数を宣言するとき
式として評価する.最後に、スタンドアローンの関数を宣言するとき、エンジンとしてエンジンとして解釈され、名前を期待するか、例外をスローします.
実際にスタンドアローン関数式を作成するには、構文パーサをトリックとして解釈し、式として解釈する必要があります.実際にはいくつかの方法がありますが、最も一般的な方法は括弧内の関数をラップすることです:
もう一度、私たちは、もう一つの括弧でそれを追加することによって、オブジェクトに評価の直後に式を実行することができます:
ES 6での矢印関数の導入により、IFEを宣言する最も一般的な方法は以下の通りです.
なぜですか?
どのようにIifes有用ですか?いくつかの異なる用途があります.まず最初に、あなたのコードのトップレベルでは、async/waitを使用できないという規則を回避します.
結論
以上です.私は、あなたが私がそれを書いたように、このポストを読んでいるIifesについて多くを学んだことを望みます!
おそらく次のようになります.
(() => {
console.log('Hello, world');
})();
定義されて、すぐに実行される関数はかなり単純な概念です、しかし、それは実際にどのように働きますか?なぜあなたはそれを使用しますか?すべての括弧のwhats?いくつかの基本的な概念を経て、JSエンジンがどのようにこのコードブロックを解析するかを理解しましょう.
文対式
まず、文と表現の違いを理解することが大切です.
ステートメントは、単にいくつかのタイプの作業を行う実行のスタンドアローンユニットです.簡単な例は
if
文がある場合、その条件はtrue
.対照的に、式はいくつかのタイプの仕事も実行することができる実行の単位です、そして、それから値に下げられます(または評価されます).例えば、式
3 > 2
は2つの値を比較し、true
.JSでは、関数は文か式のどちらかであるので、これは重要です.関数文は以下のようになります:
function greet() {
console.log('Hello, world');
}
JSエンジンがこのスニペットを解釈すると、この関数のメモリ空間を割り当て、名前を作成します.greet
- はメモリ内のスペースを指している.次に、この関数を1つの括弧で名前を追加することで実行したり、呼び出したりできます.greet()
.一方、関数式は次のようになります.
var greet = function() {
console.log('Hello, world');
}
ここで、JSエンジンは、変数のためにメモリのスペースを最初に割り当てるでしょうgreet
に設定するundefined
. 次に、関数式を評価した瞬間、オブジェクトを作成し、関数本体の内部でコードを設定します.最後に、代入演算子のオペランドを使用して代入式を評価します.=
) - それがオブジェクトと変数です.代入式はgreet
変数は、以前に作成したオブジェクトのメモリ内のアドレスを指します.「オブジェクト」という単語の使用によって混乱するかもしれません.本当に、JSでは、関数は実際にオブジェクトの特別なタイプです.関数オブジェクトには
[[Code]]
関数の実際の本体を保持します.として、1つの括弧をgreet()
エンジンは単にプロパティを探して実行します.即時関数実行
関数式を実行するのは、変数への代入後に行う必要はありません.これを評価する式の直後にペアのペアを追加し、その直後に実行します.
var greet = function() {
console.log('Hello, world');
}();
これは本当にiifeです.ブラウザでこのスニペットを実行すると、ログがすぐに発生することがわかります.ただし、変数の検査greet
それはあなたに設定されますundefined
. 関数オブジェクトを保持してはいけませんか?その理由を理解するには、operator precedence table on MDN .
この表は、演算子が評価される順序を示します.'優先度'列でより高い数の演算子は、より低い数のものの前に評価されます.
代入演算子の優先順位を探す場合
=
) 我々は、それが2であるとわかります.関数呼び出し演算子の値を探す場合は...()
) 私たちは、それが18であるのを見ます.したがって、エンジンがスニペットを解釈する順序は以下の通りです.
メモリのアドレスを名前で割り当てる
greet
に設定するundefined
.2)関数オブジェクトを作成する関数式を評価します.
3 )関数を実行します.関数は明示的な返り値を持たないので、この式は
undefined
.4 )最後の評価結果を変数に代入する
greet
.当然のことながら、関数が明示的な戻り値を持っていたなら、変数に代入します.
var greet = function() {
return 'Hello, world';
}();
これは実際にはiIFE、ちょうどその最も人気のあるフォームではありません.あなたがしたいことはスタンドアローン関数式を持ち、それを実行することです.単独表現
JSエンジンはどこにも使われない無駄な表現を解釈することを気にしません.
3; // number expression
"I'm a string" // string expression
{ name: 'object literal' } // object literal expression
上記の式は全てリテラル値に評価され、すぐに捨てられます.ブラウザで上記を実行した場合、エラーはスローされません.ただし、関数式で同じことをしようとすると、function(name) {
console.log('Hello, ' + name);
}
関数ステートメントは関数名を必要としますがそれはちょうど声明と言います?
実際、関数文と関数式の違いは、キーワード
function
, しかし、むしろ、それが我々のコードで語彙的に座るところ.代入演算子のオペランドとして関数を宣言するとき
=
, エンジンはそれを式として評価することを知っている.他の関数やオブジェクトメソッドのパラメータとして関数を宣言するとき、エンジンも式として評価する.最後に、スタンドアローンの関数を宣言するとき、エンジンとしてエンジンとして解釈され、名前を期待するか、例外をスローします.
実際にスタンドアローン関数式を作成するには、構文パーサをトリックとして解釈し、式として解釈する必要があります.実際にはいくつかの方法がありますが、最も一般的な方法は括弧内の関数をラップすることです:
(function(name) {
console.log('Hello, ' + name);
});
括弧の外側の集合は' grouping operator 'です.を参照する場合MDN documentation この関数では、式の評価の優先順位を制御します.として、それはすべての表現になることを含んでいる期待している.したがって、スタンドアロン関数式を作成しました.もう一度、私たちは、もう一つの括弧でそれを追加することによって、オブジェクトに評価の直後に式を実行することができます:
(function(name) {
console.log('Hello, ' + name);
})();
今回、括弧は「関数呼び出し」演算子です.このように、1つの括弧は、それが私たちのコードで語彙的にどこに座るかによって、3つの異なるものでありえます:グループ化演算子がそのスタンドアローンの場合、関数呼び出し演算子がその名前または引数リストにそれの後であるとき、関数呼び出し演算子に追加されますfunction
キーワード.ES 6での矢印関数の導入により、IFEを宣言する最も一般的な方法は以下の通りです.
((name) => {
console.log('Hello, ' + name);
})();
矢印関数は、this
or super
キーワード.別のポストのトピック.なぜですか?
どのようにIifes有用ですか?いくつかの異なる用途があります.まず最初に、あなたのコードのトップレベルでは、async/waitを使用できないという規則を回避します.
(async () => {
// fetch some data or do some other async thing here
})();
つ目は、グローバルな名前空間を汚染するのを避けるためです.(() => {
// some initiation code
let firstVariable;
let secondVariable;
})();
// firstVariable and secondVariable will be discarded after the function is executed.
結論
以上です.私は、あなたが私がそれを書いたように、このポストを読んでいるIifesについて多くを学んだことを望みます!
Reference
この問題について(すぐに呼び出された関数式を理解する), 我々は、より多くの情報をここで見つけました https://dev.to/yvesnrb/understanding-immediately-invoked-function-expressions-iifes-1mobテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol