Почему постфиксная запись JavaScript отличается от C и Perl?

Я учусь для экзамена на JavaScript в данный момент. Я также получил немного знания C и Perl, таким образом, я знаком с префиксом и постфиксной записью на всех трех языках.

Я сделал экзамен практики онлайн для него и одну ошибку, которую я сделал, был в оценке следующего кода:

var x = 10;
x += x--;

Теперь, я думал, что это оценит к 19, потому что это было бы 10 + 10, затем вычло бы 1 для создания 9. Но обратная связь, которую я получил, была то, что это было неправильно, и это на самом деле оценивает к 20. Я думал, что звучал немного подозрительным, таким образом, я проверил его в документе HTML, и это выпустило 20 снова. Я затем попробовал эквиваленты в C и Perl и обоих оцененных к 19.

Кто-либо может объяснить мне, почему JavaScript оценивает ответ как 20, когда другие языки оценивают его к 19? Ответ, который я получил от теста, был не слишком четким мне:

Инкремент ++ и декремент - операторы может быть помещен или прежде или после операнда. Если инкрементный или оператор понижения помещается перед операндом операция сразу происходит. Если инкрементный или оператор понижения помещается после операнда изменение в значении операнда не очевидно до следующего раза, когда к операнду получают доступ в программе. Таким образом выражение x + = x - эквивалентно x = x + 10, который оценивает к 20.

6
задан Matthew Daly 14 February 2010 в 22:28
поделиться

4 ответа

Если расширить оператор

x += x--;

до более подробного кода JS

x = x + (function(){ var tmp = x; x = x - 1; return tmp; })();

, результат будет иметь смысл, так как он будет оцениваться как

x = 10 + (function(){ var tmp = 10; x = 10 - 1; return tmp; })();

, то есть 20. Имейте в виду, что JS оценивает выражения слева направо, включая составные присваивания, т.е. значение x кэшируется перед выполнением x - .


Вы также можете думать об этом так: предполагая порядок оценки слева направо, JS анализирует присвоение как

x := x + x--

, тогда как Perl будет использовать

x := x-- + x

. Я не вижу никаких убедительных аргументов за или против любого выбора, так что это просто невезение, что разные языки ведут себя по-разному.

6
ответ дан 9 December 2019 в 22:33
поделиться

Обычно значение x уменьшается после присвоения. Этот пример может прояснить ситуацию (запустить в консоли Firebug)

var x = y =10;    
x += y--;        
console.log(x , y); // outputs 20 9
1
ответ дан 9 December 2019 в 22:33
поделиться

В C, строка

x += x--;

- это неопределенное поведение. Похоже, что ваш конкретный компилятор обрабатывает ее так:

oldx = x--;
x = x + oldx

Однако спецификация ECMAScript действительно указывает op= - и он получает значение левой части перед оценкой правой части.

Так что это будет эквивалентно:

oldx = x--;
x = oldx + oldx
1
ответ дан 9 December 2019 в 22:33
поделиться

В C / C ++ каждую переменную можно изменить только один раз в каждом операторе (я думаю, что точная терминология такова: только один раз между двумя кодовыми точками, но я не уверен).

Если вы пишете

x += x--;

, вы меняете значение x дважды:

  • вы уменьшаете x с помощью постфиксного оператора
  • , вы устанавливаете значение x с помощью присваивания

Хотя вы можете напишите это, и компилятор не будет на это жаловаться (не уверен, вы можете проверить разные уровни предупреждений), результат не определен и может быть разным для каждого компилятора.

3
ответ дан 9 December 2019 в 22:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: