web-dev-qa-db-ja.com

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

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

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

(function () {

})();
686
Exitos

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

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

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

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

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

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

Updateこれは非常に人気のあるトピックなので、IIFEは ES6の矢印関数 (-のように書くこともできます) Gajus が指摘した コメント内 ):

((foo) => foo)('foo value')
798
gion_13

作成直後に実行されるのは単なる匿名関数です。

あたかもあなたがそれを変数に代入し、その直後にそれを使ったかのように、変数なしでのみ。

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

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

$(function(){
});

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

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

即時呼び出し関数式(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
45
令狐葱

無名関数を宣言してから呼び出します。

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

それはすぐに実行するということです。

そうすれば:

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
25
Neal

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

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

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

次の例では、countはすぐに呼び出された関数の外では利用できません。すなわち、countのスコープは関数から漏れません。とにかくすぐに呼び出される関数の外側でアクセスしようとするならば、あなたはReference Errorを得るべきです。

(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);  // Reference Error: count is not defined

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

私はそれをCurly Jailと呼びます。

20
Undefined
(function () {
})();

これはIIFE(即時起動関数式)と呼ばれます。有名なジャバスクリプトデザインパターンの一つ、そしてそれは現代のモジュールパターンの心と魂です。名前が示すとおり、作成後すぐに実行されます。このパターンは、独立した、またはプライベートな実行範囲を作成します。

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

IIFEによるブロックスコープのシミュレーション

IIFEを使用することによるパフォーマンス上の利点は、ウィンドウ、ドキュメントなどの一般的に使用されるグローバルオブジェクトをスコープ参照を減らすことによって引き渡すことができることです(Javascriptはローカルスコープでプロパティを探し、グローバルスコープまで連鎖する方法を思い出してください)。そのため、ローカルスコープでグローバルオブジェクトにアクセスするには、以下のようにルックアップ時間を短縮します。

(function (globalObj) {
//Access the globalObj
})(window);
13
Gurucharan M K

いいえ、この構文は命名のためのスコープを作成するだけです。あなたが部分的にそれを破るならば、あなたはあなたが外部のものを持っていることを見ることができます

(...)();

これは関数呼び出しです。括弧の中には、

function() {}

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

11

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

JSのIIFEを理解するために、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エンジンによって「undefined」値が割り当てられます。
-実行中(実行コンテキスト-実行フェーズ)、機能オブジェクトはオンザフライで作成され(まだ実行されていない)、「greet」変数に割り当てられ、呼び出すことができます「greet( 'somename')」を使用します。

。すぐに呼び出されるFuntion式:

例:

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

console.log(greeting)  // Namaste Santosh. 

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

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は意図せずにグローバルオブジェクトと衝突しない安全なコードを記述します。

9
Santosh Pillai

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

W3Schoolsの自己呼び出し機能の説明 をご覧ください。

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

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

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

関数宣言を自己起動することはできません。

6
James Hill

これは自己起動型の無名関数です。定義されている間に実行されます。つまり、この関数は定義され、定義の直後に自動的に呼び出されます。

最初の()括弧内の関数は名前を持たない関数であり、次の();括弧で定義された時点で呼び出されることがわかります。そして、この2番目の()括弧内に任意の引数を渡すことができます。これは、最初の括弧内にある関数で取得されます。この例を参照してください。

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

ここであなたが渡している 'object'は、関数のシグネチャでそれをつかんでいるので、 'obj'によって関数内でアクセス可能です。

5

ここで始める:

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*

関数をすぐに呼び出します - oops:

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
Jim Flood

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

コード

var same_name = 1;

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

console.log(same_name);

この出力を生成します:

2
1

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

2
Daniel

自己実行型無名関数作成後すぐに実行されます。

これが有用である1つの短くてダミーの例は以下のとおりです。

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);

そのため、毎回リストを作成するのではなく、一度だけ作成します(オーバーヘッドが少なくなります)。

2
usoban

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

もう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];
    }
  }
})();
1
Shishir Arora

これは 無名関数 で、これは 自己呼び出し です。一般に即時呼び出し関数式(IIFE)として知られています。

1
Keith.Abramo

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

以下の関数がiife.jsという名前のファイルに書かれているとします。

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

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

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

1
bpjoshi

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

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

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

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

0
abdulbarik

通常、プログラムに書いた直後に関数を呼び出すことはしません。ごく簡単に言うと、関数を作成した直後にその関数を呼び出すと、その名前はIIFEと呼ばれます。

0
KawaiKx

自己誘発匿名関数が使用される理由は、ISが呼び出されることを意図したコードを「セットアップ」するため、他のコードによって呼び出されるべきではないためです。

言い換えれば、プログラムの開始時に「クラスを作成する」プログラムのようなものです。インスタンス化された後(自動的に)、利用可能な関数は匿名関数によって返される関数のみです。隠された」関数は、状態(スコープの作成中に設定された変数)とともに、まだそこにあります。

とてもかっこいい。

0
kiwicomb123

次のコード

(function () {

})();

すぐに呼び出される関数式と呼ばれます (IIFE).

Javascriptの( yourcode )演算子は強制的に式に変換するため、関数式と呼ばれます。 関数式 関数宣言 の違いは次のとおりです。

// declaration:
function declaredFunction () {}

// expressions:

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

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

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

関数オブジェクトに評価される式が得られたら、すぐに invoke / ()演算子で関数オブジェクトを呼び出すことができます。例えば:

(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

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 {}
0
James Lin

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

作成できる2つの方法IIFE

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

OR

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

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

0
Rinoy Ashokan