2012-01-10 114 views
5

我試圖做一個遞歸匿名函數。如何讓這個javascript工作?

下面是函數:

(function (i) { 
    console.log(i); 
    if (i < 5) this(i + 1) 
})(0) 

我知道 「這」 是窗口對象。有沒有辦法調用這個函數?

+1

**最好的**要做的就是讓它不是一個匿名函數,而是一個函數聲明語句定義的函數。 – Pointy 2012-01-10 22:35:47

回答

12

arguments.callee屬性可以使用。

(function(i){console.log(i);if(i<5)arguments.callee(i+1)})(0) 

另一種實現相同功能的方法是命名函數。外面的範圍,名稱將不可用:

(function tmp(i){console.log(i);if(i<5)tmp(i+1)})(0); //OK, runs well 
alert(typeof tmp); // Undefined 


注意,使用 arguments.callee財產的嚴格模式被禁止:

"use strict"; 
(function(){arguments.callee})(); 

拋出:

TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them

+1

謝謝!我會睡得更聰明。 – 2012-01-10 22:32:00

+4

請注意,'arguments.callee'已被棄用(如果您曾經在JavaScript會議上聽到過它的聲音,那麼它會大聲地說出),並且將來不會被支持。它也很慢。另外,當用函數*表達式*(而不是聲明語句)定義函數時,命名函數是有風險的,因爲[瀏覽器有時候會做奇怪的事情。](http://kangax.github.com/nfe/) – Pointy 2012-01-10 22:34:59

+0

沒有想到在這個線程上學習一個新詞。 「多才多藝」是太棒了。 – 2015-01-19 02:50:03

1

啊...遞歸的函數形式.... [[[compback sci class flashback]]]

你可以使用一個輔助功能:

function X(f) { return f.apply(this, arguments); } 
X(function(me, n) { return n<=1 ? n : n*me(me,n-1); }, 6); 

(返回720;這是階乘函數,遞歸的典型的例子)

這可以反過來被匿名:

(function (f) { return f.apply(this, arguments); })(
    function(me, n) { return n<=1 ? n : n*me(me,n-1); }, 
    6); 

或專用於一個參數的函數,爲了避免applyarguments

(function (f,x) { return f(f,x); })(
    function(me, n) { return n<=1 ? n : n*me(me,n-1); }, 
    6); 

(兩者都返回720)

這個使用助手函數的技巧可以讓你的函數接收它精靈作爲它的第一個參數,從而自稱。

適應你的例子:

(function (f,x) { return f(f,x); })(
    function(me, i) { console.log(i); if (i<5) me(me,i+1); }, 
    0) 

如預期在Firebug(原木0,1,2,3,4,5安慰)

1

您提供一個名稱的匿名函數的作品,在這裏我給它一個名字「_」,儘管它被命名了,但它仍然是匿名的。

(function _(i) { 
    console.log(i); 
    if (i < 5){ _(i + 1); } 
})(0);