Pourquoi la arguments.callee.caller
propriété a- t-elle été dépréciée en JavaScript?
Il a été ajouté puis déconseillé en JavaScript, mais il a été complètement omis par ECMAScript. Certains navigateurs (Mozilla, IE) l'ont toujours pris en charge et n'ont aucun plan sur la carte pour supprimer le support. D'autres (Safari, Opera) l'ont adopté, mais la prise en charge sur les navigateurs plus anciens n'est pas fiable.
Y a-t-il une bonne raison de mettre cette précieuse fonctionnalité dans les limbes?
(Ou alternativement, existe-t-il une meilleure façon de saisir la poignée de la fonction d'appel?)
javascript
ecma262
pcorcoran
la source
la source
<b>
et<i>
retournés (oui, ceux-ci ont été dépréciés à un moment donné).Réponses:
Les premières versions de JavaScript ne permettaient pas les expressions de fonction nommées, et à cause de cela, nous ne pouvions pas créer une expression de fonction récursive:
Pour contourner cela, a
arguments.callee
été ajouté afin que nous puissions faire:Cependant, c'était en fait une très mauvaise solution car cela (en conjonction avec d'autres arguments, les appels et les problèmes de l'appelant) rend l'inline et la récursivité de la queue impossibles dans le cas général (vous pouvez y parvenir dans certains cas en traçant etc., mais même le meilleur code est sous-optimal en raison de vérifications qui ne seraient pas nécessaires autrement). L'autre problème majeur est que l'appel récursif obtiendra un autre
this
valeur , par exemple:Quoi qu'il en soit, EcmaScript 3 a résolu ces problèmes en autorisant les expressions de fonction nommées, par exemple:
Cela présente de nombreux avantages:
La fonction peut être appelée comme n'importe quelle autre depuis votre code.
Il ne pollue pas l'espace de noms.
La valeur de
this
ne change pas.C'est plus performant (accéder à l' objet arguments coûte cher).
Oups,
Je viens de réaliser qu'en plus de tout le reste, la question portait sur
arguments.callee.caller
, ou plus précisémentFunction.caller
.À tout moment, vous pouvez trouver l'appelant le plus profond de n'importe quelle fonction sur la pile, et comme je l'ai dit ci-dessus, regarder la pile d'appels a un seul effet majeur: cela rend un grand nombre d'optimisations impossibles, ou beaucoup plus difficiles.
Par exemple. si nous ne pouvons pas garantir qu'une fonction
f
n'appellera pas une fonction inconnue, alors il n'est pas possible de s'alignerf
. Fondamentalement, cela signifie que tout site d'appel qui peut avoir été trivialement inline accumule un grand nombre de gardes, prenez:Si l'interpréteur js ne peut pas garantir que tous les arguments fournis sont des nombres au moment de l'appel, il doit soit insérer des vérifications pour tous les arguments avant le code intégré, soit il ne peut pas aligner la fonction.
Maintenant, dans ce cas particulier, un interpréteur intelligent devrait être en mesure de réorganiser les contrôles pour être plus optimal et de ne vérifier aucune valeur qui ne serait pas utilisée. Cependant, dans de nombreux cas, ce n'est tout simplement pas possible et il devient donc impossible de s'aligner.
la source
this
donc je pense que cela n'a pas d'importance si l' appelé est bon ou mauvais. En outre, appelé et l' appelant ne sont « déconseillés » en mode strict (ECMAScript ed 5, décembre 2009), mais je suppose que cela n'a pas été connu en 2008 lorsque olliej affiché.this
ifthis
est la portée globale. Dans tous les autres cas, la valeur dethis
va changer après le premier appel récursif, donc je pense que les parties de votre réponse en faisant allusion à la préservation dethis
ne sont pas vraiment valables.arguments.callee.caller
n'est pas déconseillé, bien qu'il utilise la propriété. ( vous donnera juste une référence à la fonction actuelle)Function.caller
arguments.callee
Function.caller
, bien que non standard selon ECMA3, est implémenté sur tous les principaux navigateurs actuels .arguments.caller
est déconseillé en faveur de et n'est pas implémenté dans certains des principaux navigateurs actuels (par exemple Firefox 3).Function.caller
La situation n'est donc pas idéale, mais si vous souhaitez accéder à la fonction appelante en Javascript sur tous les principaux navigateurs, vous pouvez utiliser la propriété, soit accessible directement sur une référence de fonction nommée, soit à partir d'une fonction anonyme via la propriété.
Function.caller
arguments.callee
la source
arguments.callee
est interdit en mode strict. Cela m'a également rendu triste, mais il vaut mieux ne plus l'utiliser.arguments.callee.caller
est déconseillé en mode strict ES5: "Une autre fonctionnalité déconseillée était arguments.callee.caller, ou plus précisément Function.caller." ( Source )Il vaut mieux utiliser des fonctions nommées que arguments.callee:
est mieux que
La fonction nommée aura accès à son appelant via la propriété de l' appelant :
ce qui est mieux que
La dépréciation est due aux principes de conception actuels d'ECMAScript .
la source
Juste une extension. La valeur de "ceci" change pendant la récursivité. Dans l'exemple suivant (modifié), factorial obtient l'objet {foo: true}.
la factorielle appelée la première fois obtient l'objet, mais ce n'est pas le cas pour les appels récursifs.
la source
this
doit être maintenu, écrivezfactorial.call(this, n-1)
que j'ai trouvé en écrivant du code récursif, qu'il n'y en a généralement pasthis
, outhis
fait référence à un nœud dans une arborescence et en fait, c'est bien qu'il change.