JavaScriptの(function(){})()構文とは何ですか?


790

以前はこれが何を意味するのかを知っていましたが、今は苦労しています...

これは基本的に言っていdocument.onloadますか?

(function () {

})();

20
ところで、この関数を「自己呼び出し」と呼ぶ人がいますが、それは明らかに正しくありません。iifeという用語には、正確さという利点があります。
AakashM

6
これは、この構造の優れた説明を提供します。「IIFE」という用語の発祥の地でもあります。benalman.com/news/2010/11/…– jeremysawesome 2012
1


2
この構成の命名については、こちらご覧くださいこの構成目的、および技術的な説明(およびここ)についてお読みください。構文については、括弧が必要な理由それらの場所を確認してください
Bergi 14

回答:


854

これは、即時に呼び出される関数式、または略してIIFEです。作成された直後に実行されます。

これは、任意のイベント(などdocument.onload)のイベントハンドラーとは関係ありません。
括弧の最初のペア内の部分を検討してください。.... itは正規関数式です。次に、最後のペアを確認します。これは通常、関数を呼び出す式に追加されます。この場合、以前の表現です。(function(){})();(function(){})();

(他の通常の関数のように)IIFE内で使用されるすべての変数はそのスコープの外からは見えないため、このパターンはグローバル名前空間の汚染を回避しようとするときによく使用されます。
このため、この構造をのイベントハンドラーと混同したのはこのwindow.onloadためです。

(function(){
  // all your code here
  var foo = function() {};
  window.onload = foo;
  // ...
})();
// foo is unreachable here (it’s undefined)

Guffaによって提案された修正

関数は、解析された後ではなく、作成された直後に実行されます。スクリプトブロック全体は、コードが実行される前に解析されます。また、コードの解析は、コードが実行されることを自動的に意味するわけではありません。たとえば、IIFEが関数内にある場合、関数が呼び出されるまでコードは実行されません。

更新 これはかなり人気のあるトピックであるため、IIFEはES6の矢印関数を使用して作成することもできますGajusコメントで指摘しように)。

((foo) => {
 // do something with foo here foo
})('foo value')

@ gion_13作成フェーズと解析フェーズの違いは何ですか?
akantoword 2016年

1
@jlei私の見たところ、jsプログラムのライフサイクルには、解析、作成/コンパイル、実行のフェーズが含まれます。実際の実装(および名前付け:)))はブラウザーによって異なる場合がありますが、解析エラー、ホイスト、およびランタイムエラーを監視することで、コード内のこれらのフェーズを特定できます。個人的にはレベルが低すぎるため、プログラマが制御できるものではないため、これに関するリソースは多くありません。なんらかの説明はこのSO投稿にあります:stackoverflow.com/a/34562772/491075
gion_13

@sam firatすべての中で、バリアン宣言と新しいキーワードがあります。つまり、この例では、コンストラクター(無名関数式)によって定義された新しいオブジェクトをインスタンス化し、IIFEの例のように関数を呼び出すのではなく、新しい演算子を介して呼び出されます。確かに、関数はそのコンテンツのクロージャのように機能しますが、これはまったく異なるユースケースです。
gion_13 2017年

これはグローバル名前空間をどのように汚染していますか?とにかくfooは関数の外では利用できません。 function(){ var foo = '5'; }
Pankaj

1
@Pankaj —単独で使用すると、構文的に有効なJSでもありません(これは関数式ですが、式のコンテキストではないため、構文エラーとして扱われます)。
クエンティン

109

これは、作成された直後に実行される匿名関数です。

変数に割り当ててすぐに使用した場合と同じように、変数はありません。

var f = function () {
};
f();

jQueryには、あなたが考えているかもしれない同様の構成があります:

$(function(){
});

これは、readyイベントをバインドする短い形式です。

$(document).ready(function(){
});

しかし、上記の2つの構成はIIFEではありません。


83
DOMの準備ができないときに、それらが呼び出されているので、最後の二つは、本当にIIFEsではありませんすぐに
svvac

15
@swordofpain:はい、そうです、それらはIIFEではありません。
グッファ、2014年

2番目のスニペットを考慮した@swordofpain; add()をIIFEに変換することによって、関数の最後に何らかの値があるでしょうか?
timebandit

最後のセミコロンは必要ですか?
FrenkyB 2017年

@FrenkyB必要ではありませんが、推奨されます(JavaScriptでは実際にはセミコロンは実際には必要ありませんが、良い方法です)。これらはそれぞれ、関数宣言ではなく、たまたま無名関数を含むステートメントです。
Ledivin 2017年

52

すぐに呼び出される関数式(IIFE)は、すぐに関数を呼び出します。これは単に、定義が完了した直後に関数が実行されることを意味します。

さらに3つの一般的な表現:

// Crockford's preference - parens on the inside
(function() {
  console.log('Welcome to the Internet. Please follow me.');
}());

//The OPs example, parentheses on the outside
(function() {
  console.log('Welcome to the Internet. Please follow me.');
})();

//Using the exclamation mark operator
//https://stackoverflow.com/a/5654929/1175496
!function() {
  console.log('Welcome to the Internet. Please follow me.');
}();

戻り値に特別な要件がない場合は、次のように記述できます。

!function(){}();  // => true
~function(){}(); // => -1
+function(){}(); // => NaN
-function(){}();  // => NaN

または、次のようにすることもできます。

~(function(){})();
void function(){}();
true && function(){ /* code */ }();
15.0, function(){ /* code */ }();

あなたも書くことができます:

new function(){ /* code */ }
31.new function(){ /* code */ }() //If no parameters, the last () is not required

4
最後のものは31.new「無効な構文です

9
同じことを書く方法がたくさんあるのはなぜですか?!! > _ <私はこの言語が好きではありません
Awesome_girl

6
aaandの勝者は;(function(){}());
Roko C. Buljan 2017年

Crockford設定の説明は非常に役に立ちました。たとえば、jQuery tiny-pubsub gistが1つのバージョンから別のバージョンに切り替わった(ファイルの最後で変更を確認できます)など、私が実際に目にした違いを説明しています。 t理由を理解する。
icc97

1
@Awesome_girl:同じことを書く方法はたくさんあるわけではありません。JSには、任意の値型を操作できる演算子を備えたルーズタイプシステムがあるということです。あなたがすることができ1 - 1、あなたは同じくらい簡単に行うことができますtrue - function(){}。これは1つだけです(中置減算演算子)が、意味のない異なるオペランドを使用します。

31

それは無名関数を宣言し、それを呼び出します:

(function (local_arg) {
   // anonymous function
   console.log(local_arg);
})(arg);

「引数」は、関数内のローカルコンテキストで使用される「arg」として参照される外部変数だと思いますか?
Dalibor

@Dalibor arguments特別です。私の推測では、名前が行くちょうど裏返し回答です

29

つまり、すぐに実行します。

だから私がするなら:

var val = (function(){
     var a = 0;  // in the scope of this function
     return function(x){
         a += x;
         return a;
     };
})();

alert(val(10)); //10
alert(val(11)); //21

フィドル:http : //jsfiddle.net/maniator/LqvpQ/


2番目の例:

var val = (function(){
     return 13 + 5;
})();

alert(val); //18

1
私はそれが自分の呼び出しを証明しているのかわかりませんか?
Exitos

1
@Exitosは、その関数を返すためです。2つ目の例を示します。
Naftali別名Neal

非常にわかりやすい+1
Adiii 2018年

24

その構造は、即時に呼び出される関数式(IIFE)と呼ばれ、即座に実行されます。インタプリタがその関数に到達したときに自動的に呼び出される関数と考えてください。

最も一般的なユースケース:

最も一般的な使用例の1つは、を介して作成される変数のスコープを制限することですvar。で作成された変数のvarスコープは関数に限定されているため、この構成(特定のコードの関数ラッパー)は、変数のスコープがその関数からリークしないようにします。

次の例でcountは、はすぐに呼び出される関数の外では使用できません。つまり、スコープはcount関数からリークしません。ReferenceErrorとにかくすぐに呼び出された関数の外でアクセスしようとすると、を取得するはずです。

(function () { 
    var count = 10;
})();
console.log(count);  // Reference Error: count is not defined

ES6代替(推奨)

ES6では、およびを使用して変数を作成できるようにletなりましたconst。どちらもブロックスコープです(var関数スコープとは異なります)。

したがって、前述のユースケースにIIFEの複雑な構成を使用する代わりに、はるかに単純なコードを記述して、変数のスコープが目的のブロックからリークしないようにすることができます。

{ 
    let count = 10;
}
console.log(count);  // ReferenceError: count is not defined

この例では、コードのブロックに限定letするcount変数を定義するために使用countし、中括弧で作成しました{...}

私はそれを「カーリー刑務所」と呼びます。


10
私はカーリー刑務所の命名が好きです。多分それは固執するでしょう:)
gion_13

15
(function () {
})();

これはIIFE(Immediately Invoked Function Expression)と呼ばれます。有名なJavaScriptデザインパターンの1つであり、現代のモジュールパターンの心臓部です。名前が示すように、作成された直後に実行されます。このパターンは、分離された、またはプライベートな実行範囲を作成します。

ECMAScript 6より前のJavaScriptは字句スコープを使用していたため、ブロックスコープのシミュレーションにIIFEが使用されました。(ECMAScript 6を使用するletと、およびconstキーワードの導入によりブロックスコープが可能になります。) 字句スコープに関する問題のリファレンス

IIFEを使用したブロックスコープのシミュレーション

生命維持のを使用した場合のパフォーマンス上の利点は次のように一般的に使用されるグローバルオブジェクトを渡す機能であるwindowdocumentスコープのルックアップを減らすことによって、引数として、など。(JavaScriptはローカルスコープでプロパティを検索し、グローバルスコープまでチェーンを上っていくことを思い出してください)。したがって、ローカルスコープのグローバルオブジェクトにアクセスすると、以下のようにルックアップ時間が短縮されます。

(function (globalObj) {
//Access the globalObj
})(window);

IIFEの2番目の括弧を理解するための要点を提供していただきありがとうございます。また、グローバル変数を定義で定義することにより、グローバル変数のルックアップ時間の利点を明確にするために
Arsal

11

いいえ、この構成は名前付けのスコープを作成するだけです。あなたがそれを部分的に壊すならば、あなたはあなたが外部を持っていることがわかります

(...)();

それが関数呼び出しです。括弧内には次のものが含まれます。

function() {}

それは無名関数です。構造内でvarを使用して宣言されたものはすべて、同じ構造内でのみ表示され、グローバル名前空間を汚染しません。


11

これは、Javascriptですぐに呼び出される関数式です。

JSでIIFEを理解するために、それを分解してみましょう。

  1. :値を返すもの
    例:Chromeコンソールで以下を試してください。これらはJSでの表現です。
a = 10 
output = 10 
(1+3) 
output = 4
  1. 関数式
    例:
// Function Expression 
var greet = function(name){
   return 'Namaste' + ' ' + name;
}

greet('Santosh');

関数式のしくみ:
-JSエンジンが初めて実行されるとき(実行コンテキスト-フェーズの作成)、この関数(=の右側)は実行されず、メモリに保存されません。変数「greet」には、JSエンジンによって「未定義」の値が割り当てられます。
-実行中(実行コンテキスト-実行フェーズ)、機能オブジェクトはその場で作成され(まだ実行されていません)、「greet」変数に割り当てられ、「greet( 'somename')」を使用して呼び出すことができます。

3.すぐに呼び出される関数式:

例:

// IIFE
var greeting = function(name) {
    return 'Namaste' + ' ' + name;
}('Santosh')

console.log(greeting)  // Namaste Santosh. 

IIFEの仕組み
-関数宣言の直後の「()」に注意してください。すべてのfuntionオブジェクトには、呼び出し可能な「CODE」プロパティがアタッチされています。そして、 '()'括弧を使用してそれを呼び出す(または呼び出す)ことができます。
-したがって、ここでは、実行(実行コンテキスト-実行フェーズ)中に、関数オブジェクトが作成され、同時に実行され ます。つまり、関数オブジェクトではなく、あいさつ変数に戻り値(文字列)があります。

JSでのIIFEの典型的な使用例:

次のIIFEパターンは非常に一般的に使用されます。

// IIFE 
// Spelling of Function was not correct , result into error
(function (name) {
   var greeting = 'Namaste';
   console.log(greeting + ' ' + name);
})('Santosh');
  • ここで2つのことを行っています。a)関数式を中括弧()で囲みます。これは、構文パーサーに()内に配置されたものはすべて式(この場合は関数式)であり、有効なコードであることを伝えます。
    b)この関数は、最後に()を使用して同時に呼び出しています。

したがって、この関数は同時に作成されて実行されます(IIFE)。

IIFEの重要なユースケース:

IIFEはコードを安全に保ちます。
-関数であるIIFEには独自の実行コンテキストがあります。つまり、その内部で作成されたすべての変数はこの関数に対してローカルであり、グローバル実行コンテキストと共有されません。

アプリケーションでiife.jsと一緒に使用されている別のJSファイル(test1.js)があるとします(以下を参照)。

// test1.js

var greeting = 'Hello';

// iife.js
// Spelling of Function was not correct , result into error
(function (name) { 
   var greeting = 'Namaste';
   console.log(greeting + ' ' + name);
})('Santosh');

console.log(greeting)   // No collision happens here. It prints 'Hello'.

したがって、IIFEは、意図せずにグローバルオブジェクトと衝突しない安全なコード作成するのに役立ちます


IIFE内で関数を作成する場合、他のいくつかのjsまたはjsxファイル(つまり、reactコンポーネント)でそれらにアクセスするにはどうすればよいですか。
石岩

IIFEを使用していませんが、greeting変数はグローバルGreeting変数と衝突しません。そこでの利点は何ですか?
Willy David Jr

6

これは、自己呼び出し型の無名関数です。

W3Schoolsによる自己呼び出し関数の説明を確認してください。

関数式は「自己呼び出し」にすることができます。

自己呼び出し式は、呼び出されることなく、自動的に呼び出されます(開始されます)。

関数式は、式の後に()が続く場合、自動的に実行されます。

関数宣言を自分で呼び出すことはできません。


3
(function named(){console.log("Hello");}());<-自己実行の名前付き関数
bryc '17 / 08/17

@bryc名前を必要としない関数に名前を付けるのはなぜですか。
RicardoGonzales 2017年

2
@RicardoGonzales再帰推測
bryc '27 / 06/27

5

これは、自己呼び出しの無名関数です。定義中に実行されます。つまり、この関数が定義され、定義の直後に呼び出されます。

構文の説明は次のとおりです。最初の()括弧内の関数は名前のない関数であり、次の();括弧によって、定義時に呼び出されていることがわかります。そして()、最初の括弧内にある関数で取得されるこの2番目の括弧内の引数を渡すことができます。この例を見てください:

(function(obj){
    // Do something with this obj
})(object);

ここで、渡した「オブジェクト」は、関数シグネチャで取得しているため、「obj」によって関数内でアクセスできます。


2
この質問には既に承認済みの回答があり、あなたの回答には、承認済みの回答でカバーされていないものは何も追加されていません。したがって、この答えを書く必要はまったくありませんでした。
Aadit M Shah 2015

3
私は複数の答えを読むのが好きです。時々、どちらか一方の言い回しが違いを生むことがあります。

括弧の2番目のセットが何のためにあるのかを知らせてくれたので、追加したと思いました。少なくともここで私が見たのはより明確でした。
ジョニー

私のお気に入り サンプルIIFEの両端にはパラメーターがあり、2つの間のマッピングがわかりやすくなっています。
スティーブンW.ライト

4

ここから始める:

var b = 'bee';
console.log(b);  // global

関数に入れると、もはやグローバルではなくなります-あなたの第一の目標です。

function a() {
  var b = 'bee';
  console.log(b);
}
a();
console.log(b);  // ReferenceError: b is not defined -- *as desired*

関数をすぐに呼び出します-おっと:

function a() {
  var b = 'bee';
  console.log(b);
}();             // SyntaxError: Expected () to start arrow function, but got ';' instead of '=>'

括弧を使用して、構文エラーを回避します。

(function a() {
  var b = 'bee';
  console.log(b);
})(); // OK now

関数名は省略できます。

(function () {    // no name required
  var b = 'bee';
  console.log(b);
})();

それ以上複雑にする必要はありません。


2
構文エラーは、矢印関数について話している。私が理解しているように、これはjsの新機能であり、数年前には存在しませんでしたが、IIFEにはありました。つまり、括弧はおそらく構文エラーを回避するために最初に使用されたのでしょうが、違うのでしょうか?
JCarlosR 2017

@JCarlosの質問に答えてもらえますか?IIFEがアロー関数よりもずっと前に来たことを彼が正しく指摘しているので、ラッピングが必要な理由を理解するのに役立ちます。
Script47

@ Script47コメントにJCarlosの質問に対する答えがありません。新しい質問を作成して投稿することができます。きっと良い答えが得られるでしょう。
ジム・洪水

@JCarlosは、エラーをスローするものを実行すると、Uncaught SyntaxError: Unexpected token )矢印関数についての説明ではなく、実際に取得します。アロー関数のエラーをスローすることで、フィドルを共有できますか?
Script47

2

自己実行匿名関数。作成されるとすぐに実行されます。

これが役立つ短いダミーの例は次のとおりです。

function prepareList(el){
  var list = (function(){
    var l = []; 
    for(var i = 0; i < 9; i++){
     l.push(i);
    }
    return l;
  })();

  return function (el){
    for(var i = 0, l = list.length; i < l; i++){
      if(list[i] == el) return list[i];
    }
    return null;
  }; 
} 

var search = prepareList();
search(2);
search(3);

そのため、毎回リストを作成する代わりに、1回だけ作成します(オーバーヘッドが少ない)。


1
書かれているように、検索は各呼び出しでリストを再構築します。これを回避するには、(1)リストを作成し、(2)検索関数を、作成したリストにアクセスできるクロージャとして返す必要があります。これは、匿名の自己呼び出しフォームを使用して簡単に行うことができます。jsfiddle.net/BV4bTを参照してください。
ジョージ

説明できますか...オーバーヘッドが少ない..私はこの部分を理解します
HIRA THAKUR

2
オーバーヘッドとは、実行する必要のない作業を意味します。各関数呼び出しで配列にデータを入力する必要はありません。そのため、例の配列はself-execによって入力されます。初めての無名関数。しかし、私は自分の答えを間違えたようです。適切な例については、ジョージのコメントのリンクを参照してください。
usoban 2013年

2

自己実行機能は通常、コンテキストをカプセル化し、名前の共謀を回避するために使用されます。(function(){..})()内で定義する変数はグローバルではありません。

コード

var same_name = 1;

var myVar = (function() {
    var same_name = 2;
    console.log(same_name);
})();

console.log(same_name);

この出力を生成します:

2
1

この構文を使用することで、JavaScriptコードの他の場所で宣言されたグローバル変数との衝突を回避できます。


1
正解です。myVarが最初に実行されるため、出力は2になり、次に1になります
Dalibor 2015年

1
あなたの説明は関数のスコープを説明するのにうまくいきますが、それがすぐに実行される理由を説明するには不十分です。それを変数に割り当てることは自己敗北であり、それが複数回実行されることを意図するかもしれません。 var same_name = 1; var myVar = function() { var same_name = 2; console.log(same_name); }; myVar(); console.log(same_name); 同じ結果になります。
domenicr

2

これはIIFE-即時に呼び出される関数式と呼ばれます。構文と使用法を示す例を次に示します。変数の使用範囲を関数までに限定し、それ以降は使用しません。

(function () {
  function Question(q,a,c) {
    this.q = q;
    this.a = a;
    this.c = c;
  }

  Question.prototype.displayQuestion = function() {
    console.log(this.q);
    for (var i = 0; i < this.a.length; i++) {
      console.log(i+": "+this.a[i]);
    }
  }

  Question.prototype.checkAnswer = function(ans) {
    if (ans===this.c) {
      console.log("correct");
    } else {
      console.log("incorrect");
    }
  }

  var q1 = new Question('Is Javascript the coolest?', ['yes', 'no'], 0);
  var q2 = new Question('Is python better than Javascript?', ['yes', 'no', 'both are same'], 2);
  var q3 = new Question('Is Javascript the worst?', ['yes', 'no'], 1);

  var questions = [q1, q2, q3];

  var n = Math.floor(Math.random() * questions.length)

  var answer = parseInt(prompt(questions[n].displayQuestion()));
  questions[n].checkAnswer(answer);
})();

1

IIFE(即時に呼び出される関数式)は、スクリプトがロードされてすぐに実行される関数です。

iife.jsという名前のファイルに記述された以下の関数を考えます。

(function(){
       console.log("Hello Stackoverflow!");
   })();

上記のコードは、iife.jsをロードするとすぐに実行され、 ' Hello Stackoverflow!「開発者ツール」コンソール。

詳細な説明については、即時に呼び出される関数式(IIFE)を参照してください。


1

もう1つの使用例は、キャッシュオブジェクトがグローバルではないメモ化です。

var calculate = (function() {
  var cache = {};
  return function(a) {

    if (cache[a]) {
      return cache[a];
    } else {
      // Calculate heavy operation
      cache[a] = heavyOperation(a);
      return cache[a];
    }
  }
})();

0

即時に呼び出される関数式(IIFE)は、作成されるとすぐに実行される関数です。イベントや非同期実行とは関係ありません。以下に示すように、IIFEを定義できます。

(function() {
     // all your code here
     // ...
})();

括弧の最初のペアfunction(){...}は、括弧内のコードを式に変換します。括弧の2番目のペアは、式から生成された関数を呼び出します。

IIFEは、自己呼び出しの無名関数として説明することもできます。その最も一般的な使用法は、varを介して作成される変数のスコープを制限するか、名前の衝突を回避するためにコンテキストをカプセル化することです。


0

自己喚起匿名関数が使用される理由は、(関数と変数にスコープを与えることに加えて)呼び出されることになるコードを「セットアップ」するため、他のコードによって呼び出されないようにするためです。

つまり、これらはプログラムの最初に「クラスを作成する」プログラムのようなものです。それらが(自動的に)インスタンス化された後、使用できる関数は、無名関数から返されるものだけです。ただし、その他のすべての '非表示の関数は、状態(スコープの作成中に設定された変数)とともに、まだ存在しています。

とてもかっこいい。


0

次のコード:

(function () {

})();

即時呼び出し関数式(IIFE)と呼ばれます

これは( yourcode )、JavaScript の演算子が式を強制するため、関数式と呼ばれます。関数式関数宣言の違いは次のとおりです。

// declaration:
function declaredFunction () {}

// expressions:

// storing function into variable
const expressedFunction = function () {}

// Using () operator, which transforms the function into an expression
(function () {})

式は、単一の値に評価できる一連のコードです。上記の例の式の場合、この値は単一の関数オブジェクトでした。

関数オブジェクトに評価される式を作成したら()演算子を使用して関数オブジェクトをすぐに呼び出すことができます。例えば:

(function() {

  const foo = 10;        // all variables inside here are scoped to the function block
  console.log(foo);

})();

console.log(foo);  // referenceError foo is scoped to the IIFE

なぜこれが便利なのですか?

大きなコードベースを処理しているときや、さまざまなライブラリをインポートしているときは、名前が競合する可能性が高くなります。IIFE内で関連する(したがって、同じ変数を使用している)コードの特定の部分を記述する場合、すべての変数と関数名はIIFEの関数ブラケットにスコープされます。これにより、名前が競合する可能性が減り、不注意な名前を付けることができます(たとえば、プレフィックスを付ける必要がない)。


0

ES6構文では(簡単な例を探してこのページに着地しているため、自分用に投稿しています):

// simple
const simpleNumber = (() => {
  return true ? 1 : 2
})()

// with param
const isPositiveNumber = ((number) => {
  return number > 0 ? true : false
})(4)

0

この機能を自己呼び出し機能といいます。自己呼び出し(自己実行とも呼ばれる)関数は、その定義の直後に呼び出される(呼び出される)名前のない(匿名)関数です。詳細はこちら

これらの関数が行うことは、関数が定義されると、関数がすぐに呼び出されることです。これにより、時間とコードの余分な行が節約されます(別の行で呼び出すのと比較して)。

次に例を示します。

(function() {
    var x = 5 + 4;
    console.log(x);
})();


0

これは、これを使用する理由のより詳細な説明です。

「IIFEを使用する主な理由は、データのプライバシーを確​​保することです。JavaScriptのvarは変数をそれらの包含関数にスコープ指定するため、IIFE内で宣言された変数には外部からアクセスできません。」

http://adripofjavascript.com/blog/drips/an-introduction-to-iffes-immediately-invoked-function-expressions.html


0

これは関数式であり、Immediately Invoked Function Expression(IIFE)の略です。IIFEは、作成された直後に実行される関数です。したがって、関数が呼び出されて実行されるまで待機する必要がある関数ではなく、IIFEはすぐに実行されます。例としてIIFEを作成してみましょう。2つの整数を引数として取り、合計を返すadd関数があるとします。これにより、add関数をIIFEにできます。

ステップ1:関数を定義する

function add (a, b){
    return a+b;
}
add(5,5);

ステップ2:関数宣言全体を括弧で囲んで関数を呼び出す

(function add (a, b){
    return a+b;
})
//add(5,5);

ステップ3:関数をすぐに呼び出すには、呼び出しから「追加」テキストを削除します。

(function add (a, b){
    return a+b;
})(5,5);

IFFEを使用する主な理由は、関数内でプライベートスコープを保持するためです。確認したいJavaScriptコードの中で、グローバル変数をオーバーライドしていないことを確認してください。グローバル変数をオーバーライドする変数を誤って定義することがあります。例で試してみましょう。iffe.htmlというhtmlファイルがあり、bodyタグ内のコードが

<body>
    <div id = 'demo'></div>
    <script>
        document.getElementById("demo").innerHTML = "Hello JavaScript!";
    </script> 
</body>

さて、上記のコードは何の質問もなく実行されます。今度は、ドキュメントという変数を誤ってまたは意図的にクリアしたと仮定します。

<body>
    <div id = 'demo'></div>
    <script>
        document.getElementById("demo").innerHTML = "Hello JavaScript!";
        const document = "hi there";
        console.log(document);
    </script> 
</body>

あなたはにendupうにSyntaxError:非設定可能なグローバルプロパティ文書の再宣言を。

ただし、変数名のドキュメントをクリアしたい場合は、IFFEを使用してクリアできます。

<body>
    <div id = 'demo'></div>
    <script>
        (function(){
            const document = "hi there";
            this.document.getElementById("demo").innerHTML = "Hello JavaScript!";
            console.log(document);
        })();
        document.getElementById("demo").innerHTML = "Hello JavaScript!";
    </script> 
</body>

出力:

ここに画像の説明を入力してください

別の例で試してみましょう。次のような電卓オブジェクトがあるとします。

<body>
    <script>
        var calculator = {
            add:function(a,b){
                return a+b;
            },
            mul:function(a,b){
                return a*b;
            }
        }
        console.log(calculator.add(5,10));
    </script> 
</body>

まあそれは魅力のように機能しています。もし誤って電卓オブジェクトの値を割り当て直したらどうなるでしょうか。

<body>
    <script>
        var calculator = {
            add:function(a,b){
                return a+b;
            },
            mul:function(a,b){
                return a*b;
            }
        }
        console.log(calculator.add(5,10));
        calculator = "scientific calculator";
        console.log(calculator.mul(5,5));
    </script> 
</body>

はい、あなたはTypeErrorで終わるでしょう:calculator.mulは関数iffe.htmlではありません

しかし、IFFEの助けを借りて、別の変数名計算機を作成して使用できるプライベートスコープを作成できます。

<body>
    <script>
        var calculator = {
            add:function(a,b){
                return a+b;
            },
            mul:function(a,b){
                return a*b;
            }
        }
        var cal = (function(){
            var calculator = {
                sub:function(a,b){
                    return a-b;
                },
                div:function(a,b){
                    return a/b;
                }
            }
            console.log(this.calculator.mul(5,10));
            console.log(calculator.sub(10,5));
            return calculator;
        })();
        console.log(calculator.add(5,10));
        console.log(cal.div(10,5));
    </script> 
</body>

出力: ここに画像の説明を入力してください


-1

ブラケットの2つのセットは少し混乱するように思いますが、Googleの例で別の使用法を見ました。それらは同様の何かを使用しました。これが理解を深めるのに役立つことを願っています。

var app = window.app || (window.app = {});
console.log(app);
console.log(window.app);

したがって、windows.appが定義されていない場合は、window.app = {}すぐに実行され、条件の評価中にwindow.appが割り当てられる{}ため、結果は両方でappありwindow.app、になる{}ため、コンソール出力は次のようになります。

Object {}
Object {}

-1

通常、プログラムに書き込んだ直後に関数を呼び出すことはありません。非常に簡単に言えば、作成直後に関数を呼び出すことを、IIFEと呼びます。


-1

通常、JavaScriptコードはアプリケーション内でグローバルスコープを持っています。その中でグローバル変数を宣言すると、他の目的のために、開発の他の領域で同じ重複変数を使用する可能性があります。この重複により、エラーが発生する可能性があります。そのため、関数式を直接呼び出すことでこのグローバル変数を回避できます。この式は自己実行式です。このIIFE式内のコードを作成すると、グローバル変数はローカルスコープとローカル変数のようになります。

IIFEを作成する2つの方法

(function () {
    "use strict";
    var app = angular.module("myModule", []);
}());

または

(function () {
    "use strict";
    var app = angular.module("myModule", []);
})();

上記のコードスニペットでは、「var app」がローカル変数になりました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.