Почему эти заявления работают по-разному в JavaScript?
Недавно я проверил сладкий маленький код для обмена двумя переменными с помощью функции XOR
. Для этого я использовал JavaScript.
Пусть x и y - две переменные и x = 4, y = 6
.
x = x ^ y;
y = y ^ x;
x = x ^ y;
Он легко меняет переменные. Обратите внимание, что я сохраняю x
и y
разные, чтобы предотвратить сглаживание, которое может произойти из-за первого XOR
.
Затем, наблюдая за выражением, я написал:
x = x ^ (y = y ^ (x = x ^ y ));
Это изменяет переменную y
правильно, но делает x
всегда 0
.
Кроме того, x ^= y ^= x ^= y;
, который также представляется эквивалентным выражением, дает тот же неверный результат, что и во втором случае.
Тем не менее, все эти операторы выполняются на Java и эквивалентны одинаковому результату.
Я также использовал строгий режим с JavaScript.
Являются ли эти три утверждения каким-то образом не эквивалентными на JavaScript или я пропустил что-то критическое здесь?
Ответы
Ответ 1
x = x ^ y;
y = y ^ x;
x = x ^ y;
Это работает, потому что ему нравится
x_1 = x_0 ^ y_0;
y_1 = y_0 ^ x_1;
x_2 = x_1 ^ y_1;
Затем
x_final = x_2 = x_1 ^ y_1 = x_0 ^ y_0 ^ y_0 ^ x_1 = x_0 ^ y_0 ^ y_0 ^ x_0 ^ y_0
= y_0
y_final = y_1 = y_0 ^ x_1 = y_0 ^ x_0 ^ y_0
= x_0;
Ваш x = x ^ (y = y ^ (x = x ^ y ));
похож на
x_1 = x_0 ^ y_0;
y_1 = y_0 ^ x_1;
x_2 = x_0 ^ y_1;
Затем
x_final = x_2 = x_0 ^ y_1 = x_0 ^ y_0 ^ x_1 = x_0 ^ y_0 ^ x_0 ^ y_0
= 0
y_final = y_1 = y_0 ^ x_1 = y_0 ^ x_0 ^ y_0
= x_0;
Это сработало бы, если бы вы использовали x = (y = y ^ (x = x ^ y )) ^ x;
.
Это потому, что JS анализирует выражения слева направо и вы хотите, чтобы x
было измененным значением, а не начальным.