Почему постфиксная нотация JavaScript отличается от C и Perl? - PullRequest
6 голосов
/ 15 февраля 2010

Я сейчас учусь на экзамен по 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.

Ответы [ 4 ]

6 голосов
/ 15 февраля 2010

Расширение оператора

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

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

3 голосов
/ 15 февраля 2010

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

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

x += x--;

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

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

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

1 голос
/ 15 февраля 2010

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

var x = y =10;    
x += y--;        
console.log(x , y); // outputs 20 9
1 голос
/ 15 февраля 2010

В С, строка

x += x--;

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

oldx = x--;
x = x + oldx

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

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

oldx = x--;
x = oldx + oldx
...