Почему эти заявления работают по-разному в 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 было измененным значением, а не начальным.