javascript: 再帰的な匿名関数? 質問する

javascript: 再帰的な匿名関数? 質問する

基本的な再帰関数があるとします。

function recur(data) {
    data = data+1;
    var nothing = function() {
        recur(data);
    }
    nothing();
}

次のような匿名関数がある場合、これをどのように実行すればよいでしょうか。

(function(data){
    data = data+1;
    var nothing = function() {
        //Something here that calls the function?
    }
    nothing();
})();

この関数を呼び出した関数を呼び出す方法が欲しいです... 呼び出された関数の名前を教えてくれるスクリプトをどこかで見たことがありますが (どこだったかは思い出せません)、今のところその情報は思い出せません。

ベストアンサー1

あなたできる関数を「関数宣言」ステートメントではなく値として作成する場合でも、関数に名前を付けます。言い換えると、次のようになります。

(function foo() { foo(); })();

スタックを吹き飛ばす再帰関数です。そうは言っても、 おそらく これをしたくないだろう一般的に、Javascript のさまざまな実装には奇妙な問題があるためです。注記(これはかなり古いコメントです。Kangax のブログ投稿で説明されている問題の一部/多く/すべては、より新しいブラウザで修正される可能性があります。)

このような名前を付けると、関数の外部では名前が見えなくなります (そうはならないはずですが、それが奇妙な点の 1 つです)。Lisp の「letrec」のようなものです。

についてはarguments.callee、「厳密」モードでは許可されておらず、一部の最適化が困難になるため、一般的には悪いことだと考えられています。また、予想よりもはるかに遅くなります。

編集— 自分自身を呼び出すことができる「匿名」関数の効果を実現したい場合は、次のようにします (関数をコールバックなどとして渡すことを前提としています)。

asyncThingWithCallback(params, (function() {
  function recursive() {
    if (timeToStop())
      return whatever();
    recursive(moreWork);
  }
  return recursive;
})());

これは、IEで壊れない、安全で使いやすい関数を定義するものです。宣言ステートメントは、名前がグローバル名前空間を汚染しないローカル関数を作成します。ラッパー (完全に匿名の) 関数は、そのローカル関数を返すだけです。

おすすめ記事