Pergunta

JavaScript faz conversões automáticas funky com objetos:

var o = {toString: function() {return "40"; }};
print(o + o);
print((o+1)+o);
print((o*2) + (+o));

imprimirá:

4040
40140
120

Isto porque +, se qualquer um dos argumentos são objetos / cordas, vai tentar converter todos os argumentos para cordas, em seguida, concatenar-los. Se todos os argumentos são números, adiciona-los juntos. * E unária + converter objetos em números usando toString (bem como valueOf, não mostrado aqui).

O que significa JavaScript fazer para o operador ++?

Foi útil?

Solução

A partir ECMAScript Language Specification

11,3 Postfix Expressões

Sintaxe

PostfixExpression:

  • LeftHandSideExpression
  • LeftHandSideExpression [sem LineTerminator aqui] ++
  • LeftHandSideExpression [sem LineTerminator aqui] -

11.3.1 Postfix Increment Operador

A produção PostfixExpression: LeftHandSideExpression [não LineTerminator aqui] ++ é avaliado da seguinte forma:

  1. Avaliar LeftHandSideExpression.
  2. Chamada GetValue (Resultado (1)).
  3. Chamada tonumber (Resultado (2)).
  4. Adicione o valor de 1 para Resultado (3), utilizando as mesmas regras para o operador + (Seção 11.6.3).
  5. Chamada PutValue (Resultado (1), Resultado (4)).
  6. Voltar Resultado (3).

Esta é pseudo código javascript de como postInc funciona:

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 disse: não é parseInt. Atualizado para refletir isso.

Outras dicas

O código a seguir ilustra bem isso:

var a = {toString: function() {return "40"; }};
nl(typeof a);
nl(typeof +a);
nl(typeof a);
nl(typeof (a++));
nl(a);
nl(typeof a);

A saída é:

object
number
object
number
41
number

Unários mais converte o objeto em um número e não modificá-lo. A ++ primeiros convertidos o objecto para um número, , em seguida, devolve o número , e, em seguida, incrementa o número, armazenando o valor em um.

Esta opõe-se a uma outra solução possível, onde a ++ seria primeiro devolver o objecto, e, em seguida, efectuar a conversão para um número e incrementação.

O operador ++ faz uma conversão "tonumber" (basicamente uma combinação de regras do tipo ea função valueOf). Basicamente, para qualquer expressão resolve

 resolveExpression++

As medidas tomadas pelo motor JS são

 <temp> = toNumber(resolveExpression);
 resolveExpression = <temp> + 1;
 <result> = <temp>

Para expressões resolver não-atômicas, por exemplo. base.resolve++ ou base["resolve"]++, etc. base é resolvido apenas uma vez e depois reutilizadas. Em qualquer caso sane isso é irrelevante, no entanto, é importante se o valor que está sendo incrementado é um objeto com uma implementação valueOf que muda o objeto base.

por exemplo.

base = {};
base.value = {valueOf:function(){base = {}; return 5;}}
base.value++;
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top