Por que a arguments.callee.caller
propriedade foi descontinuada em JavaScript?
Foi adicionado e descontinuado no JavaScript, mas foi totalmente omitido pelo ECMAScript. Alguns navegadores (Mozilla, IE) sempre o suportaram e não têm planos no mapa para remover o suporte. Outros (Safari, Opera) adotaram suporte para ele, mas o suporte em navegadores antigos não é confiável.
Existe uma boa razão para colocar essa funcionalidade valiosa no limbo?
(Ou, alternativamente, existe uma maneira melhor de controlar a função de chamada?)
javascript
ecma262
pcorcoran
fonte
fonte
<b>
e<i>
voltamos (sim, esses foram preteridos em um ponto).Respostas:
As versões anteriores do JavaScript não permitiam expressões de função nomeadas e, por isso, não conseguimos criar uma expressão de função recursiva:
Para contornar isso,
arguments.callee
foi adicionado o que poderíamos fazer:No entanto, essa foi realmente uma solução muito ruim, pois isso (em conjunto com outros argumentos, problemas de chamada e chamador) impossibilita a recursão de alinhamento e cauda no caso geral (você pode obtê-lo em casos selecionados através de rastreamento etc.), mas mesmo o melhor código está abaixo do ideal devido a verificações que de outra forma não seriam necessárias). A outra questão importante é que a chamada recursiva terá um
this
valor diferente , por exemplo:De qualquer forma, o EcmaScript 3 resolveu esses problemas, permitindo expressões de funções nomeadas, por exemplo:
Isso tem vários benefícios:
A função pode ser chamada como qualquer outra de dentro do seu código.
Não polui o espaço para nome.
O valor de
this
não muda.É mais eficiente (acessar o objeto de argumentos é caro).
Opa,
Apenas percebi que, além de tudo o mais, a questão era sobre
arguments.callee.caller
, ou mais especificamenteFunction.caller
.A qualquer momento, você pode encontrar o chamador mais profundo de qualquer função na pilha e, como eu disse acima, observar a pilha de chamadas tem um único efeito principal: torna impossível um grande número de otimizações ou muito mais difícil.
Por exemplo. se não podemos garantir que uma função
f
não chamará uma função desconhecida, não será possível incorporarf
. Basicamente, significa que qualquer site de chamada que possa ter sido trivialmente inlinável acumula um grande número de guardas, tome:Se o intérprete js não puder garantir que todos os argumentos fornecidos sejam números no momento em que a chamada é feita, ele precisará inserir verificações para todos os argumentos antes do código embutido ou não poderá incorporar a função.
Agora, nesse caso em particular, um intérprete inteligente deve ser capaz de reorganizar as verificações para que sejam mais ideais e não verificar valores que não seriam usados. No entanto, em muitos casos, isso simplesmente não é possível e, portanto, torna-se impossível alinhar.
fonte
this
isso acho irrelevante se o chamado é bom ou ruim. Além disso, callee e caller são apenas "descontinuados" no modo estrito (ECMAscript ed 5, dez 2009), mas acho que isso não era conhecido em 2008 quando olliej postou.this
ifthis
é o escopo global. Em todos os outros casos, o valor dethis
vai mudar após a primeira chamada recursiva, então eu acho que as partes de sua resposta alusivas à preservação dothis
não são realmente válido.arguments.callee.caller
é não obsoleto, apesar de não fazer uso da propriedade. ( apenas fornecerá uma referência à função atual)Function.caller
arguments.callee
Function.caller
, embora não padrão de acordo com o ECMA3, é implementado em todos os principais navegadores atuais .arguments.caller
foi descontinuado em favor de e não foi implementado em alguns dos principais navegadores atuais (por exemplo, Firefox 3).Function.caller
Portanto, a situação é menos do que ideal, mas se você quiser acessar a função de chamada em Javascript em todos os principais navegadores, poderá usar a propriedade, acessada diretamente em uma referência de função nomeada ou a partir de uma função anônima através da propriedade
Function.caller
arguments.callee
fonte
arguments.callee
é proibido no modo estrito. Isso também me deixou triste, mas é melhor não usá-lo.arguments.callee.caller
está obsoleto no modo estrito do ES5: "Outro recurso que foi descontinuado foi argumentos.callee.caller ou, mais especificamente, Function.caller." ( Source )É melhor usar funções nomeadas do que argumentos.callee:
é melhor que
A função nomeada terá acesso ao seu chamador através da propriedade do chamador :
o que é melhor que
A descontinuação ocorre devido aos princípios atuais de design do ECMAScript .
fonte
Apenas uma extensão. O valor "this" muda durante a recursão. No exemplo a seguir (modificado), o fatorial obtém o objeto {foo: true}.
O fatorial chamado primeira vez obtém o objeto, mas isso não é verdadeiro para chamadas recursivas.
fonte
this
precisar ser mantido, escreva ofactorial.call(this, n-1)
que encontrei ao escrever código recursivo, que geralmente não existethis
outhis
se refere a algum nó em uma árvore e, na verdade, é bom que isso mude.