ti-enxame.com

Arguments.callee está obsoleto - o que deveria ser usado?

Por fazer coisas como

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

Eu preciso de algo como arguments.callee. Encontrei informações em javascript.info que arguments.callee está obsoleto:

Esta propriedade foi preterida pelo ECMA-262 em favor de expressões de função nomeadas e para melhor desempenho.

Mas o que deveria ser usado? Algo assim?

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 compatível com vários navegadores?

38
TMS

Sim, é isso que, teoricamente, deveria deve ser usado. Você está certo. No entanto, ele não funciona em algumas versões do Internet Explorer, como sempre. Por isso tem cuidado. Pode ser necessário recorrer a arguments.callee, ou melhor, um simples:

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

setTimeout(callback, 100);

O que funciona no IE.

10
Ry-

Mas o que deveria ser usado? Algo assim?

Sim, você respondeu sua própria pergunta. Para mais informações, veja aqui:

Por que a propriedade argumentos.callee.caller foi reprovada em JavaScript?

Ele tem uma discussão muito boa sobre por que essa alteração foi feita.

5
Jonathan Rich

a resposta da minitech é bastante boa, mas falta mais um cenário. Sua função declarada chamada retorno de chamada, que significa duas coisas, primeiro a função é objeto na memória e, em segundo lugar, o nome da função é apenas para referência ao objeto. Se, por qualquer motivo, você quebrar a referência entre esses dois, o código proposto também não funcionará.

Prova:

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.

De página do desenvolvedor Mozilla na descrição é:

Aviso: A 5ª edição do ECMAScript (ES5) proíbe o uso de argument.callee () no modo estrito. Evite usar argumentos.callee (), dando um nome às expressões de função ou use uma declaração de função em que uma função deve se chamar.

obviamente, este é o primeiro exemplo de solução alternativa ", dando um nome às expressões de função ", mas vamos ver como podemos lidar com " ou use uma declaração de função em que uma função deve se chamar "e o que isso trará:

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

Então, podemos fazer o que quisermos com a referência de retorno de chamada:

var callback2 = callback;
callback = null;
callback2(); //will work perfectly.
1
lowselfesteemsucks