Wie funktioniert JavaScript, um den Operator ++ behandeln?
-
23-08-2019 - |
Frage
JavaScript tut flippige automatische Konvertierungen mit Objekten:
var o = {toString: function() {return "40"; }};
print(o + o);
print((o+1)+o);
print((o*2) + (+o));
druckt:
4040
40140
120
Diese ist, weil +, wenn eines der Argumente sind Objekte / Strings, werden versuchen, alle Argumente in Strings konvertieren sie dann verketten. Wenn alle Argumente Zahlen sind, fügt er sich zusammen. * Und unäre + Objekte in Zahlen konvertieren mit toString (sowie valueOf, hier nicht dargestellt).
Was ist JavaScript tun für den Operator ++?
Lösung
ECMAScript Language Specification
11.3 Postfix-Ausdrücke
Syntax
PostfixExpression:
- LeftHandSideExpression
- LeftHandSideExpression [no LineTerminator hier] ++
- LeftHandSideExpression [no LineTerminator hier] -
11.3.1 Postfix Inkrementoperator
Die Produktion PostfixExpression: LeftHandSideExpression [no LineTerminator hier] ++ wird ausgewertet wie folgt:
- Ausrechnen LeftHandSideExpression.
- Rufen Sie GetValue ((1)).
- Rufen Sie ToNumber (Ergebnis (2)).
- Fügen Sie den Wert 1 Ergebnis (3), wobei die gleichen Regeln wie bei dem + Operator (Abschnitt 11.6.3).
- Rufen Sie PutValue (Ergebnis (1), Ergebnis (4)).
- Zurück Ergebnis (3).
Dies ist Pseudo-JavaScript-Code, wie postInc funktioniert:
function postInc(a) {
var x = +a; // Converts a to a number, Section 11.4.6 Unary + Operator
a = x + 1;
return x;
}
Edit: Wie mikesamuel sagte: Es ist nicht parseInt ist. Aktualisiert dass widerzuspiegeln.
Andere Tipps
Der folgende Code zeigt dies gut:
var a = {toString: function() {return "40"; }};
nl(typeof a);
nl(typeof +a);
nl(typeof a);
nl(typeof (a++));
nl(a);
nl(typeof a);
Die Ausgabe lautet:
object
number
object
number
41
number
Unäres Plus konvertiert das Objekt in einer Reihe und es nicht ändern. a ++ zuerst das Objekt in eine Zahl umwandelt, gibt dann diese Zahl , und erhöht dann die Anzahl, den Wertes in einem Speicher.
Dies ist auf eine andere mögliche Lösung gegenüber, wo ein ++ zuerst das Objekt zurückkehren würde, und führen Sie dann die Umwandlung in eine Zahl und Inkrementierung.
Der ++
Operator hat eine „toNumber“ Umwandlung (im Grunde eine Kombination aus Typ-Regeln und die valueOf-Funktion). Grundsätzlich für jede Entschlossenheit Ausdruck
resolveExpression++
Die von dem JS-Engine genommen sind
<temp> = toNumber(resolveExpression);
resolveExpression = <temp> + 1;
<result> = <temp>
Für nicht-atomaren resolve Ausdrücke, zum Beispiel. base.resolve++
oder base["resolve"]++
usw. base
wird nur einmal aufgelöst und dann wieder verwendet werden. In jedem gesunden Fall ist dies irrelevant, aber es ist wichtig, wenn der Wert erhöht wird ein Objekt mit einer valueOf Implementierung ist, dass das Basisobjekt ändert.
zB.
base = {};
base.value = {valueOf:function(){base = {}; return 5;}}
base.value++;