Pourquoi les arguments.le destinataire de l'appel.appelant propriété obsolète en JavaScript?
Pourquoi le arguments.callee.caller
propriété obsolète en JavaScript?
Il a été ajouté, et puis obsolète en JavaScript, mais il a été complètement omis par ECMAScript. Certains navigateurs (Mozilla, IE) ont toujours soutenu, et n'ont pas de plans sur la carte à supprimer la prise en charge. D'autres (Safari, Opéra) ont adopté le soutien, mais le soutien sur les anciens navigateurs n'est pas fiable.
Est-il une bonne raison de mettre cette fonctionnalité précieuse dans les limbes?
(Ou, à l'inverse, est-il une meilleure façon d'attraper une poignée sur l'appel de la fonction?)
- Il est pris en charge par d'autres navigateurs, car tout ce qui obtient un minimum de l'utilisation généralisée deviendra un bug de compatibilité pour les autres navigateur. Si un site utilise une fonctionnalité qui n'existe que dans un navigateur, le site est rompu dans tous les autres, et généralement les utilisateurs à penser que c'est le navigateur qui est cassé.
- (Presque tous les navigateurs ont fait à un moment ou à un autre, par exemple. cette fonctionnalité (et JS lui-même) vient de Netscape, XHR origine dans IE, Toile, Safari, etc. Certains de ces éléments sont utiles et sont captés par les autres navigateurs au fil du temps (js, toile, xhr sont tous des exemples), certains (.le destinataire de l'appel) ne le sont pas.
- Votre commentaire à propos de la soutenir parce qu'il est utilisé et non pas parce que c'est une norme (ou même, bien qu'il soit déconseillé dans la norme) est très vrai! C'est pourquoi j'ai commencé principalement en ignorant les normes à chaque fois que je sens qu'ils ne sont pas de m'aider. Nous, en tant que les développeurs peuvent définir l'orientation des normes en utilisant ce qui fonctionne et pas ce que la spec dit que nous devrions faire. C'est ainsi que nous avons eu
<b>
et<i>
de retour (oui, ceux qui ont été dépréciées à un point).
Vous devez vous connecter pour publier un commentaire.
Les premières versions de JavaScript ne permet pas nommé les expressions de fonction, et ce parce que nous ne pouvions pas faire une fonction récursive expression:
Pour contourner ce problème,
arguments.callee
a été ajouté, de sorte que nous pourrions faire:Cependant, c'était effectivement une très mauvaise solution comme ceci (en conjonction avec d'autres arguments, appelant, et des problèmes de l'appelant) faire de l'in-lining et la queue de la récursivité impossible dans le cas général (vous pouvez la réaliser en cas de sélection par le biais de traçage, etc, mais même le meilleur code est sous-optimale en raison de contrôles qui autrement ne seraient pas nécessaires). L'autre problème majeur est que l'appel récursif obtiendrez un autre
this
valeur, par exemple:De toute façon, EcmaScript 3 résolu ces problèmes en permettant nommé les expressions de fonction, par exemple:
Cela a de nombreux avantages:
La fonction peut être appelée comme toutes les autres à partir de l'intérieur de votre code.
Qu'il ne pollue pas l'espace de noms.
La valeur de
this
ne change pas.Il est plus performant (l'accès à la les arguments de l'objet est cher).
Oups,
Viens de réaliser qu'en plus de tout le reste, la question était de savoir
arguments.callee.caller
, ou plus précisémentFunction.l'appelant
.À n'importe quel point dans le temps, vous pouvez trouver le plus profond de l'appelant de la fonction sur la pile, et comme je l'ai dit ci-dessus, en regardant la pile d'appel a un effet majeur: Il fait un grand nombre d'optimisations impossible, ou beaucoup, beaucoup plus difficile.
Par exemple. si nous ne pouvons pas garantir qu'une fonction
f
ne vais pas appeler une fonction inconnue, alors il n'est pas possible de l'incluref
. Fondamentalement, cela signifie que n'importe quel site d'appel qui peuvent avoir été trivialement inlinable accumule un grand nombre de gardes, de prendre:Si le js interprète ne peut pas garantir que tous les arguments sont des nombres au point que l'appel est effectué, il doit insérer des contrôles pour tous les arguments avant de les inline code, ou s'il ne peut la fonction inline.
Maintenant, dans ce cas particulier, un interprète intelligente devrait être en mesure de réorganiser les contrôles pour être plus optimale et de ne pas vérifier toutes les valeurs qui ne seraient pas utilisés. Cependant, dans de nombreux cas, c'est juste pas possible et, par conséquent, il devient impossible de la ligne.
this
donc je pense que ce n'est pas pertinent en ce qui concerne si appel qui est bon ou mauvais. Aussi, appel et de l'appelant ne sont que des "obsolète" dans le mode strict (ECMAscript ed 5, Décembre 2009), mais je suppose que ce n'était pas connue en 2008, lorsque olliej posté.arguments.callee
) afin de prendre les fonctions récursives, comme vous pouvez utiliser le Y combinator.this
est bête. C'est ce que nous avonsFunction.prototype.call
etFunction.prototype.apply
pour.this
sithis
est la portée globale. Dans tous les autres cas, la valeur dethis
est changer après le premier appel récursif, donc je pense que les pièces de votre réponse, en faisant allusion à la préservation dethis
ne sont pas vraiment valable.map
. Ce n'est pas parce JS vous permet d'écrire du code comme ça, que c'est une bonne idée. Il ignore la structure du code, et si vous n'avez pas les nommer, ils apparaîtront comme "fonction anonyme" dans les débogueurs et les profileurs. Je souhaite que les JS et les développeurs de par apprendre les concepts de la programmation pour arrêter l'écriture illisible, undebuggable, unprofilable, mal conçues et donc généralement du code bogué.!
pour en!(n>1))? 1
!
pour en!(n>1))? 1
!
signifie PAS comme un opérateur booléen dans la plupart des langages de programmation, la caisse des opérateurs javascript. L'intégralité de la déclarationreturn (!(n>1))? 1 : factorial(n-1)*n;
se traduit par: Si n n'est pas plus grand que 1 retourner 1 sinon retourner le résultat de la factorielle... En tout cas, il serait plus lisible que par le retrait de la extranous parenthèse et de la négation:return n<=1 ? 1 : factorial( n-1 ) * n
Function
constructeur. la spécification a dit: > les fonctions Anonymes sont créés dynamiquement en utilisant la Fonction intégrée de l'objet en tant que constructeur, qui est connu comme une instanciation de la Fonction > Une propriété est créé avec le nom du destinataire de l'appel et de la propriété des attributs { DontEnum }. La valeur initiale de cette propriété est la fonction de l'objet en cours d'exécution. Cela permet à des anonymes de fonctions récursives.arguments.callee.caller
est pas obsolète, bien qu'il ne faire usage de laFunction.appel deer
de la propriété. (arguments.appel deee
vais juste vous donner une référence à la fonction en cours)Function.caller
, bien que non-standard selon ECMA3, est mis en œuvre à travers les tous les principaux navigateurs actuels.arguments.appel deer
est déconseillée en faveur deFunction.caller
, et n'est pas mis en œuvre dans certains principaux navigateurs actuels (par exemple, Firefox 3).Donc, la situation n'est pas idéale, mais si vous souhaitez accéder à la fonction d'appel en Javascript dans tous les principaux navigateurs, vous pouvez utiliser le
Function.caller
de la propriété, soit d'accéder directement à une fonction nommée de référence, ou dans une fonction anonyme via learguments.callee
propriété.arguments.callee
est interdit en mode strict. Il m'a fait un peu triste, mais c'est mieux de ne plus l'utiliser.arguments.callee.caller
est obsolète dans ES5 mode strict: "une Autre fonctionnalité obsolète a été arguments.le destinataire de l'appel.de l'appelant, ou plus précisément de la Fonction.de l'appelant." (Source)Il est préférable d'utiliser fonctions nommées que les arguments.le destinataire de l'appel:
est mieux que
La fonction nommée aura accès à son appelant par le biais de la l'appelant propriété:
ce qui est mieux que
La dépréciation est due à l'actualité ECMAScript principes de conception.
Juste une extension. La valeur de "ce" changements au cours de la récursivité. Dans ce qui suit (modifié), par exemple, factorielle obtient le {foo:true} objet.
factorielle appelle le premier temps est l'objet, mais ce n'est pas vrai pour les appels récursifs.
this
doit être maintenu, écrirefactorial.call(this, n-1)
en fait, j'ai trouvé dans l'écriture récursive de code, qui, habituellement, il n'y a pas dethis
, outhis
se réfère à une certaine nœud dans un arbre et en fait c'est bon, ça change.