1

JavaScript で再帰呼び出しを検索しましたが、「名前のない」関数の再帰呼び出しを行いたいです。

Googleを使って見つけた結果はこのようなものです

function foo() {
   setTimeout("foo()",0);
}

しかし、私は次のようなものを作りたいです:

(function () { alert(this.function) })()

これは可能ですか?

4

5 に答える 5

5

に参加していない場合はstrict mode、で関数オブジェクトを取得できます。MDNarguments.calleeドキュメントを参照してください。例えば

(function () { 
    console.log(typeof arguments.callee); // "function"
    arguments.callee(); // call to itself
})(); 

しかし、そこでも示唆されているように、このステートメントを避けて、関数に識別子を与える必要があります。

(function foo() { 
    foo(); // call to itself
})(); 
于 2012-05-07T15:57:45.737 に答える
0

.callee は絶対に使用しないでください

関数に名前を付けるだけで、内部スコープ内でのみ使用できます

setTimeout(function namedFn(x) { 

  // namedFn() exists in here only (see notes below)
  console.log('hello there ' + x);

  if (!x || x < 10) { 
    namedFn(1 + x || 1);
  } 

}, 5000);

// namedFn() is undefined out here **(except for IE <= 8)**
于 2012-05-07T16:12:12.490 に答える
0

私の知る限り、あなたはできません。コールバックするには、参照 (名前または変数) が必要です。

ありますがarguments.callee、それはお勧めできません

注: arguments.callee() の使用を避け、すべての関数 (式) に名前を付けてください。

于 2012-05-07T15:59:48.433 に答える
0

基本的に、Y-Combinator と呼ばれるものを探しています (または、ウィキペディアではFixed Point Combinatorと呼んでいます)。

このブログ投稿 は良い紹介をしているようです(ざっと読んだだけで、すべてを説明できるかどうかはわかりません...)

http://blog.jcoglan.com/2008/01/10/deriving-the-y-combinator/

var Y = function(f) {
  return (function(g) {
    return g(g);
  })(function(h) {
    return function() {
      return f(h(h)).apply(null, arguments);
    };
  });
};
var factorial = Y(function(recurse) {
  return function(x) {
    return x == 0 ? 1 : x * recurse(x-1);
  };
});

factorial(5)  // -> 120

編集:私は記事からそれを盗みました、そして私は認めなければなりません、私はそれが本当に混乱していると思います.Yは次のように読む方が良いかもしれません.

var Y = function(f) {
    var c1 = function(g) {
        return g(g);
    };
    var c2 = function(h) {
        return function() {
            return f(h(h)).apply(null, arguments);
        };
    }
    return c1(c2);
};

そして、それを見ると、それが本来あるべきほど単純であるかどうかはわかりません。javascript で fixpoint コンビネータを定義することの最大の欠点は、関数が無限に再帰しないように、ある種の遅延評価が必要なことです。簡略版を投稿する前に、それについて考えたり、記事を読み直したりする必要があります。もちろん、このようなものがどれほど役立つかはわかりませんが、特にパフォーマンスに関してはそうです。最も理解しやすい(そしておそらくよりパフォーマンスの高い)解決策は、おそらく他の人が提案したように匿名ブロックを作成し、関数を通常どおり定義してブロックから返すことです。

于 2012-05-07T16:05:58.860 に答える
0

関数を値として渡すときに、関数の名前を使用できます。

setTimeout(function foo() { alert(foo); });
于 2012-05-07T16:05:59.853 に答える