¿Cómo trata JavaScript operador ++?
-
23-08-2019 - |
Pregunta
JavaScript hace conversiones automáticas cobardes con objetos:
var o = {toString: function() {return "40"; }};
print(o + o);
print((o+1)+o);
print((o*2) + (+o));
imprimirá:
4040
40140
120
Esto se debe a +, si alguno de los argumentos son objetos / cuerdas, tratarán de convertir todos los argumentos para cuerdas y luego concatenar ellos. Si todos los argumentos son números, los suma. * + Unario y convertir objetos a números con toString (así como valueOf, no mostrados aquí).
¿Qué hace JavaScript para el operador ++?
Solución
especificación del lenguaje ECMAScript
11,3 Postfix Expresiones
Sintaxis
PostfixExpression:
- LeftHandSideExpression
- LeftHandSideExpression [no LineTerminator aquí] ++
- LeftHandSideExpression [no LineTerminator aquí] -
11.3.1 Postfix Incremento del operador
La producción de PostfixExpression: LeftHandSideExpression [sin LineTerminator aquí] ++ se evalúa como sigue:
- Evaluar LeftHandSideExpression.
- Llamada GetValue (Resultado (1)).
- Llamada ToNumber (Resultado (2)).
- Añadir el valor 1 para dar como resultado (3), utilizando las mismas reglas que para el operador + (Sección 11.6.3).
- Llamada putValue (Resultado (1), Resultado (4)).
- retorno de resultado (3).
Esta es la pseudo código javascript de cómo funciona postInc:
function postInc(a) {
var x = +a; // Converts a to a number, Section 11.4.6 Unary + Operator
a = x + 1;
return x;
}
Edit: Como mikesamuel dijo: no es parseInt. Se ha actualizado para reflejar eso.
Otros consejos
El código siguiente ilustra bien esto:
var a = {toString: function() {return "40"; }};
nl(typeof a);
nl(typeof +a);
nl(typeof a);
nl(typeof (a++));
nl(a);
nl(typeof a);
La salida es:
object
number
object
number
41
number
plus unario convierte el objeto a un número y no lo modifica. a ++ primero convierte el objeto a un número, a continuación, devuelve ese número , y luego incrementa el número, almacenar el valor en a.
Esto se opone a otra posible solución, donde un ++ sería primero devolver el objeto, y luego hacer la conversión a un número y de incremento.
El operador ++
hace una conversión "ToNumber" (básicamente una combinación de reglas de tipo y la función valueOf). Básicamente para cualquier expresión resolución
resolveExpression++
Los pasos dados por el motor de JS son
<temp> = toNumber(resolveExpression);
resolveExpression = <temp> + 1;
<result> = <temp>
Para resolver expresiones no atómicas, por ejemplo. base.resolve++
o base["resolve"]++
, etc. base
se resuelve sólo una vez y luego reutilizados. En cualquier caso cuerdo esto es irrelevante, sin embargo es importante si el valor que se incrementa es un objeto con una aplicación valueOf que cambia el objeto base.
por ejemplo.
base = {};
base.value = {valueOf:function(){base = {}; return 5;}}
base.value++;