14

複数回実行する必要があるコードがある場合は、それを関数にまとめて、繰り返す必要がないようにします。さらに、ページの読み込み時に最初にこのコードを実行する必要がある場合もあります。今、私はこのようにしています:

function foo() {
   alert('hello');
}

foo();

私はむしろこのようにしたい:

(function foo() {
   alert('hello');
})();

問題は、これはページの読み込み時にのみ実行されますが、それを使用して後で呼び出そうとしても機能しfoo()ないことです。

これはスコープの問題だと思いますが、後で呼び出されたときに自己実行関数を機能させる方法はありますか?

4

4 に答える 4

33

関数が戻り値に依存していない場合は、これを行うことができます...

var foo = (function bar() {
   alert('hello');
   return bar;
})();   // hello

foo();  // hello

barこれは、名前付き関数式のローカル参照を使用して、関数を外部foo変数に返します。


または、そうであっても、戻り値を条件付きにすることができます...

var foo = (function bar() {
   alert('hello');
   return foo ? "some other value" : bar;
})();   // hello

alert( foo() );  // hello --- some other value

または、返す代わりに変数に手動で割り当てるだけです...

var foo; 
(function bar() {
   alert('hello');
   foo = bar;
})();   // hello

foo();  // hello

@RobGで指摘されているように、IE の一部のバージョンでは、識別子が外側の変数スコープにリークされます。その識別子は、作成した関数の複製を参照します。NFE IE-safe(r) を作成するには、その参照を無効にすることができます。

bar = null;

識別子は、スコープチェーンの同じ名前の識別子を引き続きシャドウすることに注意してください。無効化は役に立たず、ローカル変数は削除できないため、NFE 名は慎重に選択してください。

于 2012-06-05T00:56:02.850 に答える
4

foo()をグローバル関数、つまり のプロパティにする場合は、次のwindowようにします。

(window.foo = function() {
   alert('hello');
})();

// at some later time
foo();

最初の括弧内の式は create への割り当てを行いますfooが、関数として評価されるため、最後に ですぐに呼び出すことができます()

このパターンは、関数が値を返すことになっている場合でも機能します。

于 2012-06-05T01:29:15.890 に答える
4

外部から呼び出すには、関数が外部から見える必要があります。理想的には、渡されたコンテキスト (この場合、thisグローバル コンテキストを参照する )に自己実行関数を挿入します。

(function(context) {
  var foo = function() {
    alert('hello');
  };
  foo();
  context.foo = foo;
})(this);

...

foo();

もっと興味深いパターンはここにあります。

于 2012-06-05T01:09:08.390 に答える