2011-12-28 37 views
2

可能性の重複:
javascript function vs. (function() { … }());基本的なJavaScript:()();

申し訳ありませんが、これはあまりにも基本的なものですが、この構造は何をされた場合はどうなりますか?

(function MyFunction() { 
    /* Some codes ... */  
})(); 

多分特別な用語がありますか?検索フィールドにそのスニペットを置くのではなく、Google検索に役立ちます。

+2

これは自己呼び出す無名関数です。この宣言の外側にある 'MyFunction'は関数を参照することはありませんが、その内部では、' MyFunction'を使って自分自身を再度呼び出すことができます。 –

+0

IE(lte 8)ではMyFunctionがグローバルスコープにリークされることに注意してください:) [http://jsfiddle.net/DEn4e/](http://jsfiddle.net/DEn4e/) – abuduba

答えて

6

これは、直接呼び出しパターンと呼ばれています。それは無名関数を定義し、それを直ちに実行します。これは '私的な'変数などに便利です。あなたが正常にこれを行うだろうとした場合:

// global namespace 
var data = 'lol'; 
function getData() { 
    return data; 
} 

をグローバル名前空間内の変数データが​​あるだろうと、誰かがWebコンソールでdata = 123を入力した場合、それはあなたのスクリプトを破ることができました。直接呼び出しパターンを使用して、あなたがこれを行うことができます:

// global namespace 
/*lotsofcodehere*/ 
(function MyFunction() { 
    // closure namespace 
    var data = 'lol'; 
    this.getData = function getData() { 
    return data; 
    } 
})(); 
// global again 

をこの場合、機能のgetDataはまだグローバル名前空間に存在していますが、データは閉鎖名前空間の外部からアクセスすることはできません。

また、このパターンを使用しているときMyFunctionのは、グローバル名前空間には存在しませんわかります。それは多くの小さな言語規則の理由の一つであるが、基本的機能は、関数内でその名によって常に利用可能です。

// returns the amount of from--s needed to get to 0 :D 
// (yes, it returns it's input number :D) 
(function() { 
var i = 0, keep = false; 

this.countToZero = function(from) { 
    if(from === 0) { 
    keep = false; // don't keep i's contents on next invocation 
    return i; 
    } 
    if(!keep) i = 0; // reset i on first invocation 
    i++; 
    keep = true; 
    return countToZero(from - 1); 
} 
})(); 

これは完全に機能し、countToZero(5)はきれいに5を返します。しかし、非グローバルな名前空間で使用するとうまくいきません。関数内でこの関数を使用すると、関数のメンバープロパティとしてcountToZeroを定義します(countToZeroはアクセスできなくなるため)
これはおそらく現実的なシナリオではありませんが、この例では機能します。代わりに、上記のコードで、私たちはこの使用します:

/*code*/ 
this.countToZero = function countToZero(from) { 
    // countToZero will *always* exist here as a reference to this function! 
    /*code*/ 
    return countToZero(from); 
}; 

をこのコードは、あなたが完全にばかげ方法でそれを使用している場合でも、当然の最初のパラメータとしてのInfinityを渡した場合を除き、破ることは非常に困難です。

...私は明確な説明や素敵な、現実の例を提供するつもりだった

を言いましたか?私はしなかったことを願っています

+1

これを正しく理解すれば、その匿名関数が直ちに実行されます。しかし、戻り値、つまり 'data'をどうすれば得ることができますか?別の変数に割り当てることはできますか? – moey

+1

関数の外部から 'data'にアクセスすることはできません。しかし、関数は関数*上のすべての変数にアクセスすることができるので、 'data'は' getData'で利用できます。おそらくどこかでより良い説明があります。 'function scoping javascript'の検索クエリは、そのトリックを行うべきです;) –

+1

'data'は、定義されている関数内で利用可能です。他の関数呼び出しで引数として渡しますこれらのイベントが発生すると呼び出されるイベントにバインドすることができます。 – igorw

4

関数MyFunctionをグローバル名前空間に配置せずに作成して実行します。これは名前空間の汚染を避けるための良い方法です。実行されると、実際にはどこにも保存されなかったので、再度実行することはできません。

+1

別の機能? – moey

+0

はい、他の関数呼び出しが許可されている場所ならどこにでも置くことができます。 –

+0

あなたは可能です。 @AndrewD。 – MahdeTo

1

これは自己実行機能です。名前の有無にかかわらず、関数を定義してすぐに実行します。

+0

ありがとう、@ジョシュ。 *名前なしであなたはどうしますか? – moey

+1

@ Siku-Siku.Com '(function(){/*...*/})();' –

+0

+1超高速応答に感謝します! – moey

2

これは基本的には、グローバル名前空間にMyFunctionの中で定義された変数は、同様にグローバルで利用できなくなることofcourseのはいうまでもないそれを追加することなく、MyFunctionの内のコードを()を呼び出します。

私は、これは、例えば、非表示にする必要が再帰ロジックを持っているコードの一部を実行するために必要と一緒に時間の大半を構築する見てきました特定のサブ文書のページへの走査。

0

関数を定義した直後に関数が呼び出されます。

これはという作品:

function MyFunction() { 
    /* Some codes ... */  
} 
MyFunction(); 

しかし、それは意味し、グローバルスコープでMyFunctionをへのアクセスを持っていません - あなたはどこでも(IE < = 8 =>http://jsfiddle.net/DEn4e/除く)からのアクセスも持っていませんがそれがグローバルスコープに漏れがない変数が発生するため はそのためお勧めしません:)

+1

これは厳密には同等ではありません。例のMyFunctionは呼び出しを超えてアクセス可能であり、通常呼び出すことができます。 – MahdeTo

+1

**これは当てはまりません**あなたの場合に起こるグローバル名前空間には格納されません。 –

+0

本当ですか?つまり、次のようにアドレスバーに置かれます: 'javascript :(function MyFunction(){})(); alert(MyFunction);' – abuduba