すぐに差関数宣言と関数式を理解するために、あなたが理解したい機能を実行します。
関数の宣言
1 |
関数( [PARAM、[、PARAM、[...、PARAM]]] ) { |
関数式
1 |
せfunction_expression =関数[名]([PARAM1 [、PARAM2 [、...、paramNの]]]){ |
名前は、この場合における機能匿名関数を省略することができます。
両者の違いで
- 関数宣言は、関数式は、実行前に機能を実行するために待たなければならない、あなたが事前に呼び出すことはできません、現在のスコープを実行するために事前に呼び出すことができます。
- 関数式は直接関数の後の括弧内に呼び出すことができます。関数の宣言は、直接ブラケットの後ろに呼び出すことはできません。
コアの問題
コアの問題は、通過関数宣言と関数式で()
問題コール。
次のコードを考えてみます。
1 |
VaRの FOO = 機能() {}(); |
機能後のカッコ内の関数式を直接呼び出すことができるので、実装するためにこのコード行は、問題ありません。
1 |
機能() {}(); |
それは、デフォルトで、functionキーワードに直面したJavaScriptコードの解釈、ため、エラー関数宣言それは、エラー時に重要な関数式などの表面に到達しなかった場合、はなく、関数式ので、関数宣言は、関数名を必要とし、上記のコード関数は、関数名、最初の左括弧に上記のコードの実装におけるエラーを有していません。だから、FirefoxとChromeは本質は同じ間違いであると報告しました。
1 |
関数 FOO() {}(); |
直後に実行括弧内の式を表す式が、後関数宣言の括弧内に、ブラケットは、関数宣言の前に影響を与えないであろう、上記のコードは、と等価です。
1 |
関数 FOO() {}。 |
()
式の内部には、エラーので、空にすることはできません。
即時実行機能(生命維持)
我々は問題の核心を見つける上では、ということである()
関数式が先行されなければなりません。
すぐに関数の実行を記述するための二つの方法で見てみましょう:
1 |
(関数() { |
1 |
(関数() { |
どちらのバージョンは、関数式に匿名関数の宣言になるように設計されています。JavaScriptでは、()
オペレータ、()
内部パーサは、コードを解釈するときに自動的に、式を含むことができ、宣言を含むことができない()
表現として認識されたコードではなく、関数宣言内。
だから、理論的には、に加えて()运算符
、他の事業者と同様の効果を得ることができ、括弧、ブラケットを使用する理由、他の事業者に比べて、より安全になるので。
生命維持用
そして、ロック状態でクロージャを使用して
。1
2
3
4
5
6
7
8
9
10
11
12である
13である
14
15
16
17
大カラム 包括的な理解JavaScript関数には直ちに実行される E「> 18である
。19
20
21であり、
22は
23である
24
25
26である
27の
28
29
30
31 ISあなたがそのように考えると、iの値がロックされていないので、//は、実行しません
//実際には、forループ中で実行されたときに我々は、リンクをクリックすると
、iのクリックされた値がすでにelemsとき//そうに。長
VAR elems = 文献 .getElementsByTagName(「」)。
ため(VAR iが= 0 ; I <elems.lengthを、I ++){
elems [i]を.addEventListener('クリック'、機能(E) {
e.preventDefault();
警告('I午前リンク#' + I);
}、'false'に)。
}
//今回、我々はあなたが望む結果を得る
//は内部関数ので、すぐに実行し、iの値はlockedIndexを通過し、かつメモリにロックされている
iの値が変更されたforループの終わりにもかかわらず、//が、即時実施lockedIndex値内部機能と変わらない
VAR elems = ドキュメント .getElementsByTagNameを(「」)。
ため(VAR iが= 0 ; I <elems.lengthを、I ++){
(関数(lockedInIndex) {
elems [i]を.addEventListener('クリック'、機能(E) {
e.preventDefault();
警告('私はリンク#だ' + lockedInIndex);
}、'false'に)。
})( 私 );
}モジュールモード
IIFE内部形成一个单独是作用域,封装一下外部无法读取的私有变量,通过
return
来返回外部可以访问的数据。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29// 创建一个立即调用的匿名函数表达式
// return一个变量,其中这个变量里包含你要暴露的东西
// 返回的这个变量将赋值给counter,而不是外面声明的function自身
var counter = (function () {
var i = 0;
return {
get: function () { 戻り Iと、 }、 セット:関数(ヴァル) { I =ヴァル。 }、 インクリメント:関数(
) { リターン ++ iは、 } }。}())。
//オブジェクトの複数の属性を有するカウンタ、上記のコードの属性が実際に具体化される方法
counter.get(); // 0
counter.set(3)。
counter.increment(); // 4
counter.increment(); // 5
counter.i; //未定義私が返されていないため、オブジェクト属性は、
I; //参照エラー:私は定義されていません(私は唯一の閉鎖ために存在します)