Подтвердить что ты не робот

Унарные операторы "++" и "-" странная ситуация

Здесь тестовая ситуация для использования унарного оператора "++":

var j = 0 ;
console.log(j);
j = j++;
console.log(j);

Для этого выход:

0
0

Так как позиция оператора ++ находится в задней части операнда, поэтому его приоритет ниже приоритета назначения, я ожидал бы, что "j" сначала получит значение самого себя (i.e.0), но затем будет увеличено. Итак, почему второй вызов console.log(j) все еще показывает "0"?

Чтобы быть ясным, я знаю, что решения:

// 1)
j++;
// 2)
++j;
// 3)
j += 1;
// 4)
j = ++j;

Но мне нужно знать, почему шаг приращения не выполняется в этом конкретном сценарии, а не как его исправить!

4b9b3361

Ответ 1

Это неинтуитивное (но не "странное"!) поведение при использовании post-increment.

В заявлении j = j++ выполняется следующее:

  • Оцените LHS
    • В этом случае ничего особенного не происходит, потому что вы просто называете переменную, но это может быть не всегда так, например. foo() = j++
  • Оценить RHS
    • Возьмите текущее значение j (0) и запомните его как результат;
    • Приращение j (для получения 1);
  • Назначить RHS для LHS
    • помните, что RHS оценивает это "запоминаемое" значение j (0).

В результате получается no-op.

Ключевым моментом здесь является то, что весь RHS оценивается и выполняется пост-приращение перед окончательным назначением.


http://www.ecma-international.org/ecma-262/5.1/#sec-11.3.1
http://www.ecma-international.org/ecma-262/5.1/#sec-11.13.1

Ответ 2

В соответствии с спецификациями ECMA для оператора Postfix Increment,

  • Пусть lhs является результатом оценки LeftHandSideExpression.
  • Выбросить исключение SyntaxError, если все условия верны:
    • Тип (lhs) имеет значение Reference is true
    • IsStrictReference (lhs) истинно
    • Тип (GetBase (lhs)) - это запись среды.
    • GetReferencedName (lhs) является либо "eval", либо "arguments"
  • Пусть oldValue будет ToNumber (GetValue (lhs)).
  • Пусть newValue является результатом добавления значения 1 в oldValue, используя те же правила, что и для оператора + (см. 11.6.3).
  • Вызов PutValue (lhs, newValue).
  • Возвращает oldValue.

Итак, ясно, что новое значение сначала устанавливается на lhs (в данном случае j), а старое значение возвращается в результате выражения, которое снова устанавливается в j. Таким образом, значение не изменяется.

Ответ 3

Где ++ позволяет узнать, какое значение вы получите от него в этот момент

++j; // increment the value and then give it to me.
j++; // give me the value and then increment it.

так что вы говорили

j = j++;

установите j в значение j до того, как он будет увеличен.

Ответ 4

j = j++ означает сначала присвоить значение RHS LHS, а затем увеличить RHS на 1. С другой стороны, j = ++j означает увеличение RHS на 1, а затем присвоение его LHS

Ответ 5

j ++ означает сначала назначить, затем увеличивать

++ j означает при первом приращении, затем назначьте

Итак,

var j = 0 ;
console.log(j);
j = ++j;
console.log(j);

0
1