Как JavaScript обрабатывает оператор ++? - PullRequest
1 голос
/ 22 декабря 2008

JavaScript делает фанки автоматических преобразований с объектами:

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

напечатает:

4040
40140
120

Это связано с тем, что +, если какой-либо из аргументов является объектом / строкой, попытается преобразовать все аргументы в строки, а затем объединит их. Если все аргументы являются числами, он складывает их вместе. * и унарные + преобразовать объекты в числа с помощью toString (а также valueOf, здесь не показано).

Что делает JavaScript для оператора ++?

Ответы [ 3 ]

4 голосов
/ 22 декабря 2008

С Спецификация языка ECMAScript

11.3 Постфиксные выражения

Синтаксис

PostfixExpression:

  • ЛевостороннееВыражение
  • LeftHandSideExpression [здесь нет LineTerminator] ++
  • LeftHandSideExpression [здесь нет LineTerminator] -

11.3.1 Оператор постфиксного приращения

Производство PostfixExpression: LeftHandSideExpression [нет LineTerminator здесь] ++ оценивается следующим образом:

  1. Оценить выражение LeftHandSideExpression.
  2. Call GetValue (Результат (1)).
  3. Call ToNumber (Результат (2)).
  4. Добавьте значение 1 в Результат (3), используя те же правила, что и для оператора + (раздел 11.6.3).
  5. Call PutValue (Результат (1), Результат (4)).
  6. Результат возврата (3).

Это псевдо-код JavaScript, как работает postInc:

function postInc(a) {
  var x = +a; // Converts a to a number, Section 11.4.6 Unary + Operator
  a = x + 1;
  return x;
}

Редактировать: Как сказал mikesamuel : это не parseInt. Обновлено, чтобы отразить это.

3 голосов
/ 22 декабря 2008

Следующий код хорошо иллюстрирует это:

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

Вывод:

object
number
object
number
41
number

Унарный плюс преобразует объект в число и не изменяет его. a ++ сначала преобразует объект в число, затем возвращает это число , а затем увеличивает число, сохраняя значение в.

Это противоположно другому возможному решению, где a ++ сначала возвращает объект, а затем выполняет преобразование в число и приращение.

1 голос
/ 22 декабря 2008

Оператор ++ выполняет преобразование "toNumber" (в основном комбинация правил типа и функции valueOf). В основном для любого выражения разрешения

 resolveExpression++

Шаги, предпринятые двигателем JS:

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

Для неатомарных выражений разрешения, например. base.resolve++ или base["resolve"]++ и т. Д. base разрешается только один раз, а затем используется повторно. В любом нормальном случае это не имеет значения, однако важно, если увеличиваемое значение является объектом с реализацией valueOf, которая изменяет базовый объект.

например.

base = {};
base.value = {valueOf:function(){base = {}; return 5;}}
base.value++;
...