2016-07-21 12 views
11

Ich habe vor kurzem süßen kleinen Code ausgecheckt, um zwei Variablen mit XOR Funktion zu tauschen. Ich habe JavaScript dafür benutzt.Warum funktionieren diese Anweisungen in JavaScript anders?

Sei x und y zwei Variablen und lass x = 4, y = 6.

x = x^y; y = y^x; x = x^y;

Es tauscht schön Variablen. Beachten Sie, dass ich x und y unterschiedlich halte, um Aliasing zu verhindern, das aufgrund der ersten XOR auftreten kann.

Dann die Aussage zu beobachten, schrieb ich: x = x^(y = y^(x = x^y)); Diese Variable tauscht y richtig macht aber x immer 0.

Auch x ^= y ^= x ^= y;, die ebenfalls äquivalenter Ausdruck scheint, liefert das gleiche falsche Ergebnis wie im zweiten Fall.

Alle diese Anweisungen werden jedoch gleichwertig auf Java ausgeführt und ergeben konsistent das gleiche Ergebnis.

Ich habe auch strikten Modus mit JavaScript verwendet.

Sind diese drei Aussagen irgendwie nicht gleichwertig auf JavaScript oder fehlt mir hier etwas Kritisches?

+3

versuche 'x = (y = y^(x = x^y))^x;' stattdessen - du musst x geändert haben, bevor du es bewertest ... Das letzte andere wird nicht funktionieren, weil der erste Teil von 'x^'(Finden des Startwerts) wird durchgeführt, bevor x neu zugewiesen wird. – dandavis

+0

ein typunabhängiger Austausch ohne temp lexikalisch: 'var x = 4, y = 6; x = [y, y = x] [0]; [x, y] ' – dandavis

+0

@dandavis Deine Lösung wirkt wie ein Zauber. Vielen Dank. Ich habe meinen Fehler gefunden. Ich Idiot. Noch einmal vielen Dank. – Ozil

Antwort

4
x = x^y; 
y = y^x; 
x = x^y; 

Dies funktioniert, weil es dann

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; 

, wie

x_1 = x_0^y_0; 
y_1 = y_0^x_1; 
x_2 = x_1^y_1; 

ist Ihr x = x^(y = y^(x = x^y)); ist wie

x_1 = x_0^y_0; 
y_1 = y_0^x_1; 
x_2 = x_0^y_1; 

, dann

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; 

Es hätte funktioniert, wenn Sie x = (y = y^(x = x^y))^x; verwendet haben.

Das liegt daran, dass JS die Ausdrücke von links nach rechts analysiert, und Sie möchten, dass x der modifizierte Wert ist, nicht der ursprüngliche Wert.

+0

x^(y = y^(x = x^y)); ist nicht dasselbe wie (y = y^(x = x^y))^x; ist alles was du sagen willst, oder? – user1589188

+0

@ user1589188 Kurz gesagt, ja – Oriol