(1, eval) ("il") vs eval ("il") en JavaScript?
Je commence à lire JavaScript Modèles, certains codes qui me confond.
var global = (function () {
return this || (1, eval)('this');
}());
Voici mes questions:
Q1:
(1, eval) === eval
?
Pourquoi et comment ça fonctionne?
Q2: Pourquoi ne pas simplement
var global = (function () {
return this || eval('this');
}());
ou
var global = (function () {
return this;
}());
- J'ai mis à jour le titre parce que c'est un cas particulier. Aussi, de parenthèse pour le type spécifique de crochets: [] et {} sont entièrement différentes 🙂
Vous devez vous connecter pour publier un commentaire.
La différence entre
(1,eval)
et de la plaine de vieuxeval
est que le premier est un valeur et le dernier est une lvalue. Il serait plus évident si elle était une autre identificateur:Qui est
(1,eval)
est une expression qui donneeval
(un peu comme dire,(true && eval)
ou(0 ? 0 : eval)
serait), mais ce n'est pas une référence àeval
.Pourquoi s'en faire?
Bien, l'Ecma spec considère un référence à
eval
être un "direct eval appel", mais une expression qui ne fait que les rendementseval
pour être l'une indirecte -- et indirects eval appels sont garantis à exécuter dans la portée globale.Choses que je ne sais toujours pas:
this
d'une fonction à la portée globale pas rendement global de l'objet?Certains plus d'informations peuvent être glanées ici.
MODIFIER
Apparemment, la réponse à ma première question est, "presque toujours". Un direct
eval
exécute à partir de la actuel portée. Considérons le code suivant:Il n'est pas surprenant (heh-heh), cette affiche:
MODIFIER
Après plus d'expérimentation, je vais provisoirement dire que
this
ne peut pas êtrenull
ouundefined
. Il peut être réglé à d'autres falsy valeurs (0, ", NaN, false), mais seulement très délibérément.Je vais dire que votre source est atteint d'une légère et réversible cranio-rectale et inversion pourriez envisager de passer une semaine à la programmation Haskell.
value
vslvalue
chose (enfin, dans la pratique, peut-être, mais pas dans les mots). Ni l'ES5 eval règles (non pas que je devrait raisonnablement avoir besoin d'utilisereval
jamais). Merci!eval
a beaucoup de méchants bords tranchants et ne doit être utilisé qu'en dernier recours, et puis, très, très attentivement.innerHtml
eval
et la MemberExpression partie d'un CallExpression et se référer à la normeeval
fonction.eval
comme la cible d'un appel expression est spécial. Vous dites que l'ECMA traite référence poureval
spécial dont il n'a pas. C'est le placement dans l'appel d'expression qui est un spécial que l'expression est évaluée à la normeeval
fonction. Par exemple,var eval = window.eval; eval('1');
est toujours un direct eval etwindow.eval('1')
n'est-ce pas même si eval est une lvalue, dans ce cas aussi.eval
jamais. J'ai une vague théorie que la distinction qui est faite pour la sécurité du navigateur et le navigateur de l'utilisateur, pas pour faciliter la tâche du programmeur.Le fragment,
permettra d'évaluer correctement sur l'objet global, même en mode strict. Non le mode strict de la valeur de
this
est l'objet global, mais en mode strict, il estundefined
. L'expression(1, eval)('this')
sera toujours l'objet global. La raison de ceci implique que les règles autour indirects versets directeval
. Appels directs àeval
a la portée de l'appelant et de la chaînethis
permettrait d'évaluer à la valeur dethis
dans la fermeture. Indirecteval
s évaluer dans la portée globale comme si ils ont été exécutés à l'intérieur d'une fonction dans la portée globale. Depuis que la fonction n'est pas lui-même un strict mode de la fonction de l'objet global est passé enthis
et puis l'expression'this'
évalue à l'objet global. L'expression(1, eval)
est juste une façon élégante de la force de laeval
indirects et de retour de l'objet global.A1:
(1, eval)('this')
n'est pas le même queeval('this')
en raison des règles spéciales autour indirects verset appels directs àeval
.A2: L'original fonctionne en mode strict, les versions modifiées ne le font pas.
Pour Q1:
Je pense que c'est un bon exemple de l'opérateur virgule en JS. J'ai comme l'explication pour l'opérateur virgule dans cet article: http://javascriptweblog.wordpress.com/2011/04/04/the-javascript-comma-operator/
L'opérateur virgule évalue à la fois de ses opérandes (de gauche à droite) et renvoie la valeur de la deuxième opérande.
À T2:
(1, eval)('this')
est considérée comme indirecte eval appel, qui dans l'ES5 n'exécuter du code à l'échelle mondiale. Donc, le résultat sera le mondial le contexte.Voir http://perfectionkills.com/global-eval-what-are-the-options/#evaling_in_global_scope
Q1: de Multiples consécutifs instructions javascript, séparés par une virgule prendre la valeur de la dernière instruction. Donc:
(1, eval)
prend la valeur de la dernière qui est une fonction de référence à laeval()
fonction. Il ne semble de cette façon de faire de laeval()
appeler dans un indirectes eval appel qui sera évaluée dans le contexte global dans l'ES5. Détails expliqués ici.T2: Il doit y avoir un environnement qui n'a pas de définir une
this
, mais ne définissenteval('this')
. C'est la seule raison pour laquelle je peux penser pour que./eval\(/g
?eval
'd code est exécuté dans son propre contexte, plutôt que dans le contexte mondial ou la enfermant contexte. Une façon de contourner cela est d'indirectement référence à ce que le code en question n'.