Comment JavaScript ne traite l'opérateur ++?
-
23-08-2019 - |
Question
JavaScript ne conversions automatiques funky avec des objets:
var o = {toString: function() {return "40"; }};
print(o + o);
print((o+1)+o);
print((o*2) + (+o));
imprimera:
4040
40140
120
Ceci est parce que +, si l'un des arguments sont des objets / cordes, va essayer de convertir les chaînes les concaténer alors tous les arguments. Si tous les arguments sont des nombres, il les additionne. * Et + unaire convertir des objets à l'aide de numéros toString (ainsi que valueOf, non représentés ici).
Qu'est-ce que JavaScript ne fait pour l'opérateur ++?
La solution
De ECMAScript Language Specification
11.3 Postfix Expressions
Syntaxe
PostfixExpression:
- LeftHandSideExpression
- LeftHandSideExpression [pas LineTerminator ici] ++
- LeftHandSideExpression [pas LineTerminator ici] -
11.3.1 Postfix Increment opérateur
La production PostfixExpression: LeftHandSideExpression [pas LineTerminator ici] ++ est évalué comme suit:
- Evaluer LeftHandSideExpression.
- Appel GetValue (Résultat (1)).
- Appel ToNumber (Résultat (2)).
- Ajoutez la valeur 1 à Résultat (3), en utilisant les mêmes règles que pour l'opérateur + (Section 11.6.3).
- Appel PutValue (Résultat (1) Résultat (4)).
- Résultat de retour (3).
Ceci est pseudo code javascript de la façon dont fonctionne postInc:
function postInc(a) {
var x = +a; // Converts a to a number, Section 11.4.6 Unary + Operator
a = x + 1;
return x;
}
Edit: Comme mikesamuel dit: ce n'est pas parseInt. Mise à jour pour refléter cela.
Autres conseils
Le code suivant illustre bien ceci:
var a = {toString: function() {return "40"; }};
nl(typeof a);
nl(typeof +a);
nl(typeof a);
nl(typeof (a++));
nl(a);
nl(typeof a);
La sortie est la suivante:
object
number
object
number
41
number
plus unaire convertit l'objet en un numéro et ne modifie pas. un premier ++ convertit l'objet d'un certain nombre, retourne ensuite ce nombre , et incrémente alors le nombre, la mémorisation de la valeur de a.
Ceci est opposé à une autre solution possible, où un ++ serait d'abord renvoyer l'objet, puis faire la conversion en nombre et incrémentation.
L'opérateur ++
fait une conversion « ToNumber » (essentiellement une combinaison de règles de type et la fonction valueOf). Fondamentalement, pour toute expression de résolution
resolveExpression++
Les mesures prises par le moteur JS sont
<temp> = toNumber(resolveExpression);
resolveExpression = <temp> + 1;
<result> = <temp>
Pour les expressions de résoudre les non atomiques, par exemple. base.resolve++
ou base["resolve"]++
, etc. base
est résolu qu'une seule fois, puis réutilisés. Dans tous les cas sain d'esprit cela n'a aucune importance, mais il est important si la valeur étant incrémentée est un objet avec une implémentation valueOf qui change l'objet de base.
par exemple.
base = {};
base.value = {valueOf:function(){base = {}; return 5;}}
base.value++;