2011-12-02 76 views
33

對於做這樣的事情Arguments.callee已棄用 - 應該使用什麼?

setTimeout(function() { 
    ... 
    setTimeout(arguments.callee, 100); 
}, 100); 

我需要這樣的東西arguments.callee。我發現information at javascript.infoarguments.callee被棄用:

此屬性由ECMA-262贊成命名的函數表達式 ,並獲得更好的性能棄用

但是應該用什麼來代替?這樣的事情?

setTimeout(function myhandler() { 
    ... 
    setTimeout(myhandler, 100); 
}, 100); 
// has a big advantage that myhandler cannot be seen here!!! 
// so it doesn't spoil namespace 

順便說一句,是arguments.callee跨瀏覽器兼容?

+2

對於WH值得:[命名函數表達式揭祕](http://kangax.github.com/nfe/)。 – sdleihssirhc

+0

是的,你應該命名你的函數並在setTimeout中使用它的名字。 – kubetz

+1

[爲什麼在JavaScript中不推薦使用arguments.callee.caller屬性?](http://stackoverflow.com/questions/103598/why-was-the-arguments-callee-caller-property-deprecated-in- javascript) – cHao

回答

10

是的,這就是理論上應該使用。你是對的。但是,它一直在某些版本的Internet Explorer中不起作用。所以要小心。您可能需要依傍arguments.callee,或者說,一個簡單的:

function callback() { 
    // ... 
    setTimeout(callback, 100); 
} 

setTimeout(callback, 100); 

這確實在IE工作。

+1

等待 - 你想說'setTimeout(function myhandler(){setTimeout(myhandler ...'在某些版本的IE中不起作用嗎?這是非標準的東西嗎?我認爲這是一個非常標準的事情 – TMS

+3

@TomasT .:它*是*標準 - 但自從什麼時候IE瀏覽器完全標準化了以後?:)(好吧,也許IE10)。我記得有一段時間被絆倒了。快速測試表明這不是問題在IE7中至少可能IE6,我沒有與我一起測試 – Ryan

+0

據微軟稱,它在IE6中工作:https://docs.microsoft.com/en-us/scripting/javascript/reference/callee -property-arguments-javascript –

0

minitech答案是相當不錯的,但它缺少一個更多的場景。您的declare函數稱爲callback,這意味着兩件事,首先函數是內存中的對象,第二,函數名稱僅用於引用該對象。如果你出於任何原因打破了這兩者之間的關係,那麼所提出的代碼將無法工作。

證明:

function callback() { 
    // ... 
    setTimeout(callback, 100); 
} 

setTimeout(callback, 100); 

var callback2 = callback; //another reference to the same object 
callback = null; //break the first reference 
callback2(); //callback in setTimeout now is null. 

從描述developer Mozilla page是:

警告:ECMAScript中(ES5)的第五版禁止使用 arguments.callee的()嚴格模式。避免使用arguments.callee() 或者給函數表達式一個名字,或者使用函數必須調用自己的函數 。

顯然這是解決方法的第一個例子「由要麼給功能表達式的名稱」,但讓我們看看我們如何應對「或使用函數聲明,其中一個函數必須調用本身」和究竟會帶來:

function callback(){ 
    //... 
    setTimeout(innercall(), 100); 
    function innercall(){ 
     //innercall is safe to use in callback context 
     innercall.caller(); //this will call callback(); 
    } 
} 

然後,我們是安全的,做任何我們想用回調引用:

var callback2 = callback; 
callback = null; 
callback2(); //will work perfectly. 
+0

'呼叫者'是不好的做法,這裏的示例代碼實際上並沒有設置超時。只是不要覆蓋你的聲明函數。 – Ryan

相關問題