[解決済み] カプセル化された匿名関数の構文について説明します。
質問
概要
JavaScriptでカプセル化された匿名関数の構文の理由を説明できますか?なぜこれが機能するのか。
(function(){})();
しかし、これはそうではありません。
function(){}();
?
知っていること
JavaScriptでは、このように名前付き関数を作成します。
function twoPlusTwo(){
alert(2 + 2);
}
twoPlusTwo();
また、無名関数を作成して変数に代入することも可能です。
var twoPlusTwo = function(){
alert(2 + 2);
};
twoPlusTwo();
匿名関数を作成し、それを括弧で囲んですぐに実行することで、コードのブロックをカプセル化することができます。
(function(){
alert(2 + 2);
})();
モジュール化されたスクリプトを作成する際に、GreasemonkeyスクリプトやjQueryプラグインなどのように、現在のスコープやグローバルスコープに競合する可能性のある変数が散乱しないようにするために有効です。
さて、なぜこれがうまくいくのか、理解できました。括弧は内容を囲み、結果のみを公開します(もっと良い表現があると思います)。
(2 + 2) === 4
.
わからないこと
しかし、なぜこれが同じように機能しないのか、理解できない。
function(){
alert(2 + 2);
}();
それを説明してもらえますか?
どのように解決するのですか?
としてパースされているため、うまくいきません。
FunctionDeclaration
であり、関数宣言の名前識別子は
必須
.
括弧で囲むと、それは次のように評価されます。
FunctionExpression
また、関数式には名前を付けることも、付けないこともできます。
の文法は
FunctionDeclaration
はこのようになります。
function Identifier ( FormalParameterListopt ) { FunctionBody }
そして
FunctionExpression
s:
function Identifieropt ( FormalParameterListopt ) { FunctionBody }
ご覧のように
Identifier
(識別子
オプト
)トークンを
FunctionExpression
は省略可能なので、名前が定義されていない関数式を持つことができます。
(function () {
alert(2 + 2);
}());
または という名前 関数式になります。
(function foo() {
alert(2 + 2);
}());
括弧(正式名称は グループ化演算子 ) は式だけを囲むことができ、関数式は評価されます。
この2つの文法プロダクションは曖昧で、例えば全く同じに見えることもある。
function foo () {} // FunctionDeclaration
0,function foo () {} // FunctionExpression
パーサーは、それが
FunctionDeclaration
または
FunctionExpression
に依存しています。
コンテキスト
が表示されます。
上記の例では、2番目は式なので カンマ演算子 は、式だけを扱うこともできます。
一方
FunctionDeclaration
は、実際には"と呼ばれるものにしか出現しない可能性があります。
Program
つまり、グローバルスコープの外側にあるコードと、グローバルスコープの内側の
FunctionBody
他の関数の
ブロック内の関数は、予測できない動作につながる可能性があるため、避ける必要があります。
if (true) {
function foo() {
alert('true');
}
} else {
function foo() {
alert('false!');
}
}
foo(); // true? false? why?
上記のコードで実際に生成されるのは
SyntaxError
というのは
Block
はステートメントしか含むことができませんが (ECMAScript 仕様では関数ステートメントは定義されていません)、ほとんどの実装では許容されており、単に 2 番目の関数、つまり
'false!'
.
Mozillaの実装であるRhino、SpiderMonkeyは、異なる動作をしています。彼らの文法には
非標準の
関数ステートメント、つまり関数は
実行時
のようにパース時ではありません。
FunctionDeclaration
s. これらの実装では、最初に定義された関数を取得することになります。
関数はさまざまな方法で宣言することができます。 は次のように比較します。 :
1- 機能 のコンストラクタを変数 掛ける :
var multiply = new Function("x", "y", "return x * y;");
2- という名前の関数宣言 乗算 :
function multiply(x, y) {
return x * y;
}
3- 変数に代入される関数式 乗じる :
var multiply = function (x, y) {
return x * y;
};
4- 名前付き関数式 func_name という変数に代入されます。 乗算 :
var multiply = function func_name(x, y) {
return x * y;
};
関連
-
vue+webrtc(Tencent cloud)ライブ機能の実践を実現するために
-
[解決済み】ERROR エラーです。スイッチのname属性が指定されていないフォームコントロールの値アクセッサがない
-
[解決済み] JavaScriptで "use strict "は何をするのか、その根拠は?
-
[解決済み] let "と "var "の使い分けは?
-
[解決済み] JavaScriptでメールアドレスを検証するのに最適な方法は何ですか?
-
[解決済み] JavaScriptでオブジェクトをディープクローンする最も効率的な方法は何ですか?
-
[解決済み] とは何ですか! (not not)演算子とは何ですか?
-
[解決済み] jQueryの「exists」関数はありますか?
-
[解決済み] なぜ ++[[]][+[] +[+[]] は "10" という文字列を返すのでしょうか?
-
[解決済み] 誰かPythonで__all__を説明してくれませんか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Vue Element-uiは、アイコンを追加するためのツリーコントロールノードを詳細に実装しています。
-
元のイベントが実行されなかった後に要素を追加するためのjQueryソリューション
-
vueのグローバルがscss(mixin)を導入。
-
vue ディレクティブ v-html と v-text
-
[解決済み】SyntaxError: JSONの位置1に予期しないトークンoがある。
-
[解決済み】Node.js getaddrinfo ENOTFOUND
-
[解決済み] TypeError: $.ajax(...) is not a function?
-
[解決済み】React - TypeError: 未定義のプロパティ 'props' を読み取ることができない。
-
[解決済み】JavaScriptでインラインIF文の書き方は?
-
[解決済み】ReactJSでエラー発生 Uncaught TypeError: Super expression は null か関数でなければならず、undefined ではありません。