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 ++?

¿Fue útil?

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:

     
      
  1. Evaluar LeftHandSideExpression.
  2.   
  3. Llamada GetValue (Resultado (1)).
  4.   
  5. Llamada ToNumber (Resultado (2)).
  6.   
  7. Añadir el valor 1 para dar como resultado (3), utilizando las mismas reglas que para el operador +   (Sección 11.6.3).
  8.   
  9. Llamada putValue (Resultado (1), Resultado (4)).
  10.   
  11. retorno de resultado (3).
  12.   

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++;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top