JavaScript で再帰呼び出しを検索しましたが、「名前のない」関数の再帰呼び出しを行いたいです。
Googleを使って見つけた結果はこのようなものです
function foo() {
setTimeout("foo()",0);
}
しかし、私は次のようなものを作りたいです:
(function () { alert(this.function) })()
これは可能ですか?
JavaScript で再帰呼び出しを検索しましたが、「名前のない」関数の再帰呼び出しを行いたいです。
Googleを使って見つけた結果はこのようなものです
function foo() {
setTimeout("foo()",0);
}
しかし、私は次のようなものを作りたいです:
(function () { alert(this.function) })()
これは可能ですか?
に参加していない場合はstrict mode
、で関数オブジェクトを取得できます。MDNarguments.callee
ドキュメントを参照してください。例えば
(function () {
console.log(typeof arguments.callee); // "function"
arguments.callee(); // call to itself
})();
しかし、そこでも示唆されているように、このステートメントを避けて、関数に識別子を与える必要があります。
(function foo() {
foo(); // call to itself
})();
.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)**
私の知る限り、あなたはできません。コールバックするには、参照 (名前または変数) が必要です。
ありますがarguments.callee
、それはお勧めできません
注: arguments.callee() の使用を避け、すべての関数 (式) に名前を付けてください。
基本的に、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 コンビネータを定義することの最大の欠点は、関数が無限に再帰しないように、ある種の遅延評価が必要なことです。簡略版を投稿する前に、それについて考えたり、記事を読み直したりする必要があります。もちろん、このようなものがどれほど役立つかはわかりませんが、特にパフォーマンスに関してはそうです。最も理解しやすい(そしておそらくよりパフォーマンスの高い)解決策は、おそらく他の人が提案したように匿名ブロックを作成し、関数を通常どおり定義してブロックから返すことです。
関数を値として渡すときに、関数の名前を使用できます。
setTimeout(function foo() { alert(foo); });