Я учусь для экзамена на 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.
Если расширить оператор
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
. Я не вижу никаких убедительных аргументов за или против любого выбора, так что это просто невезение, что разные языки ведут себя по-разному.
Обычно значение x уменьшается после присвоения. Этот пример может прояснить ситуацию (запустить в консоли Firebug)
var x = y =10;
x += y--;
console.log(x , y); // outputs 20 9
В C, строка
x += x--;
- это неопределенное поведение. Похоже, что ваш конкретный компилятор обрабатывает ее так:
oldx = x--;
x = x + oldx
Однако спецификация ECMAScript действительно указывает op=
- и он получает значение левой части перед оценкой правой части.
Так что это будет эквивалентно:
oldx = x--;
x = oldx + oldx
В C / C ++ каждую переменную можно изменить только один раз в каждом операторе (я думаю, что точная терминология такова: только один раз между двумя кодовыми точками, но я не уверен).
Если вы пишете
x += x--;
, вы меняете значение x дважды:
Хотя вы можете напишите это, и компилятор не будет на это жаловаться (не уверен, вы можете проверить разные уровни предупреждений), результат не определен и может быть разным для каждого компилятора.