[解決済み] Javascriptのファイル全体を「(function(){ ... })()」のような無名関数で囲むのは何のためでしょうか?
質問
最近、Javascriptをよく読むのですが、インポートする.jsファイルに以下のようにファイル全体がラップされていることに気づきました。
(function() {
...
code
...
})();
単純なコンストラクター関数のセットではなく、このような方法をとる理由は何でしょうか?
どのように解決するのですか?
通常、名前空間(後述)を設定し、メンバ関数や変数の可視性を制御することになります。オブジェクトの定義のようなものだと思ってください。技術的な名称は 即座に呼び出される関数式 (jQueryのプラグインは通常このような書き方をしています。
Javascriptでは、関数を入れ子にすることができます。ですから、以下のようなものは合法です。
function outerFunction() {
function innerFunction() {
// code
}
}
を呼び出すことができます。
outerFunction()
が表示されますが
innerFunction()
のスコープに制限されます。
outerFunction()
に対してプライベートであることを意味します。
outerFunction()
. これは基本的に、Javascriptの変数と同じ原理です。
var globalVariable;
function someFunction() {
var localVariable;
}
対応する。
function globalFunction() {
var localFunction1 = function() {
//I'm anonymous! But localFunction1 is a reference to me!
};
function localFunction2() {
//I'm named!
}
}
上記のシナリオでは
globalFunction()
はどこからでも呼び出せますが
localFunction1
または
localFunction2
.
と書いているときにやっていること
(function() { ... })()
つまり、最初の括弧の中のコードを関数リテラルにしているのです(つまり、"オブジェクト"全体が実際には関数であることを意味します)。その後で、関数を自己呼び出しているのです(最後の
()
) を定義したところです。つまり、先ほども言ったように、プライベートなメソッド/関数やプロパティを持つことができるのが大きなメリットです。
(function() {
var private_var;
function private_function() {
//code
}
})();
最初の例では、明示的に
globalFunction
を名前で指定して実行します。つまり
globalFunction()
を実行してください。しかし、上記の例では、単に関数を定義しているわけではありません。
と
を一度に呼び出すことができます。つまり、JavaScriptファイルがロードされると、即座に実行されるのです。もちろん、そうすることもできる。
function globalFunction() {
// code
}
globalFunction();
IIFEを使用すると、グローバルスコープを汚染しないようになります。(結果的に、名前を持たないので関数を複数回呼び出すことはできませんが、この関数は一度しか実行されないので、実際には問題にはなりません。)
IIFEで素晴らしいのは、内部で何かを定義し、必要な部分のみを外部に公開することもできる点です(ネームスペースの例で、基本的に独自のライブラリやプラグインを作成することができます)。
var myPlugin = (function() {
var private_var;
function private_function() {
}
return {
public_function1: function() {
},
public_function2: function() {
}
}
})()
を呼び出すことができます。
myPlugin.public_function1()
にアクセスすることはできません。
private_function()
! というわけで、クラス定義とかなり似ています。このことをよりよく理解するために、以下のリンク先を参照することをお勧めします。
EDIT
書き忘れました。その最後の
()
のように、内部に何でも渡すことができます。例えば、jQueryのプラグインを作るときには
jQuery
または
$
というように
(function(jQ) { ... code ... })(jQuery)
つまり、ここでやっていることは、1つのパラメータを受け取る関数 (
jQ
というローカル変数、そして既知の
だけ
をその関数に送る)。そして、その関数を自己起動し、パラメータを渡します(これも
jQuery
が、しかし
これ
は外部からのもので、実際のjQueryそのものへの参照である)。 これを行う緊急の必要性はありませんが、いくつかの利点があります。
- グローバルパラメータを再定義して、ローカルスコープで意味のある名前を付けることができます。
- グローバルスコープに移動するよりもローカルスコープに移動した方が早いので、若干のパフォーマンス上の利点があります。
- 圧縮(ミニフィケーション)のメリットがあります。
先ほど、これらの関数が起動時に自動的に実行されることを説明しましたが、自動的に実行されるのであれば、誰が引数を渡しているのでしょうか? このテクニックは、必要なパラメーターがすでにグローバル変数として定義されていることを前提にしている。ですから、もしjQueryがすでにグローバル変数として定義されていなければ、この例はうまくいかないでしょう。ご想像の通り、jquery.jsは初期化時に「jQuery」というグローバル変数と、より有名な「$」というグローバル変数を定義しており、これによりjQueryが組み込まれた後でもこのコードが動作するようになっています。
関連
-
[解決済み】React - TypeError: 未定義のプロパティ 'props' を読み取ることができない。
-
[解決済み] JavaScriptで "use strict "は何をするのか、その根拠は?
-
[解決済み] JavaScriptでオブジェクトをディープクローンする最も効率的な方法は何ですか?
-
[解決済み] とは何ですか! (not not)演算子とは何ですか?
-
[解決済み] Node.jsを使うタイミングをどう判断するか?
-
[解決済み] JavaScriptの変数のスコープとは何ですか?
-
[解決済み] JavaScriptの「new」キーワードとは何ですか?
-
[解決済み] どのDOM要素にフォーカスがあるかを調べるには?
-
[解決済み] JavaScriptの(function() { } )()構文とは何ですか?
-
[解決済み】JavaScript版sleep()とは?)
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
fetch ネットワークリクエストラッパーの説明例
-
JavaScriptのクロージャの説明
-
vue+webrtc(Tencent cloud)ライブ機能の実践を実現するために
-
vue ディレクティブ v-html と v-text
-
[解決済み] Error : 未定義のプロパティ 'map' を読み取ることができません。
-
[解決済み】Uncaught SyntaxError: JSONの位置0に予期しないトークンuがあります。
-
[解決済み】Node Version Manager のインストール - nvm コマンドが見つかりません。
-
[解決済み】TypeErrorの解決方法。未定義またはヌルをオブジェクトに変換できない
-
[解決済み】 env: node: macにそのようなファイルやディレクトリはありません
-
[解決済み】ReactJSでエラー発生 Uncaught TypeError: Super expression は null か関数でなければならず、undefined ではありません。