2011-12-02 19 views
33

Per fare le cose comeArguments.callee è deprecato - cosa dovrebbe invece essere usato?

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

ho bisogno di qualcosa come arguments.callee. Ho trovato information at javascript.info che arguments.callee è deprecato:

Questa struttura è deprecato da ECMA-262 a favore del nome funzione espressioni e per migliorare le prestazioni.

Ma quale deve essere utilizzato al suo posto? Qualcosa di simile?

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

BTW, è arguments.callee compatibile con più browser?

+2

per wh vale: [espressioni di funzioni denominate demistificate] (http://kangax.github.com/nfe/). – sdleihssirhc

+0

Sì, dovresti nominare la tua funzione e usare il suo nome in setTimeout. – kubetz

+1

possibile duplicato di [Perché la proprietà arguments.callee.caller è stata deprecata in JavaScript?] (Http://stackoverflow.com/questions/103598/why-was-the-arguments-callee-caller-property-deprecated-in- javascript) – cHao

risposta

10

Sì, questo è ciò che, in teoria, deve essere utilizzato. Hai ragione. Tuttavia, non funziona in alcune versioni di Internet Explorer, come sempre. Perciò stai attento. Potrebbe essere necessario ripiegare su arguments.callee, o meglio, un semplice:

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

setTimeout(callback, 100); 

che funziona su IE.

+1

Aspetta - vuoi dire che 'setTimeout (function myhandler() {setTimeout (myhandler ...' non funzionerà in alcune versioni di IE? È una cosa non standard? Ho pensato che fosse una cosa piuttosto normale da fare – TMS

+3

@TomasT .: È * standard *, ma da quando IE è mai stato completamente standard? :) (Beh, forse IE10.) Ricordo di essermi lasciato inciampare da un po 'di tempo. Un rapido test rivela che non è un problema in IE7 almeno. Probabilmente IE6 .Non ce l'ho con me per testare. – Ryan

+0

Secondo Microsoft, funziona in IE6: https://docs.microsoft.com/en-us/scripting/javascript/reference/callee -property-arguments-javascript –

0

risposta minitech è abbastanza buona, ma manca uno scenario in più. La tua funzione di dichiarazione chiamata callback, che significa due cose, prima la funzione è l'oggetto in memoria, e il secondo, il nome della funzione è solo per fare riferimento all'oggetto. Se tu, per qualsiasi ragione, rompi il riferimento tra questi due, il codice proposto non funzionerà.

Dimostrazione:

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. 

Da developer Mozilla page nella descrizione è:

Attenzione: La 5 ° edizione di ECMAScript (ES5) vieta l'uso di arguments.callee() in modalità rigorosa. Evitare di usare arguments.callee() per dando un nome alle espressioni di funzione o utilizzare una dichiarazione di funzione in cui una funzione deve chiamarsi.

ovviamente questo è il primo esempio di soluzione "da entrambe dando funzione di espressioni un nome", ma permette di vedere come possiamo affrontare "o utilizzare una dichiarazione di funzione in cui una funzione deve chiamarsi" e ciò sarà che portano:

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

allora siamo sicuri di fare tutto ciò che vogliamo con il riferimento di richiamata:

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

'chiamante' non è una buona pratica e in questo caso il codice di esempio non sembra impostare un timeout. Basta non sovrascrivere la funzione dichiarata. – Ryan

Problemi correlati