【问题标题】:Why do these statements work differently in JavaScript?为什么这些语句在 JavaScript 中的工作方式不同?
【发布时间】:2016-07-21 17:10:36
【问题描述】:

我最近正在检查使用 XOR 函数交换两个变量的可爱小代码。我为此使用了 JavaScript。

设 x 和 y 为两个变量,设x = 4, y = 6

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

它很好地交换变量。请注意,我将 xy 保持不同,以防止由于第一个 XOR 而可能发生的混叠。

然后,观察声明,我写道: x = x ^ (y = y ^ (x = x ^ y )); 这会正确地交换变量y,但使x 总是0

另外,x ^= y ^= x ^= y; 这似乎也是等效的表达式,会产生与第二种情况相同的错误结果。

但是,所有这些语句在 Java 上的运行相同,并且始终产生相同的结果。

我还在 JavaScript 中使用了严格模式。

这三个语句在 JavaScript 上是否不等效,还是我在这里遗漏了一些关键的东西?

【问题讨论】:

  • 尝试 x = (y = y ^ (x = x ^ y )) ^ x; 代替 - 在评估之前您需要更改 x... 最后一个将不起作用,因为 x^ 的第一部分(查找起始值)在 x 之前完成重新分配。
  • 一个类型无关的swap w/o temp lexical:var x= 4, y= 6; x=[y, y= x][0]; [x,y]
  • @dandavis 一个 ES6 交换只是简单的 let x = 4, y = 6; [x, y] = [y, x];
  • @dandavis 这很好用x=(y^=(x^=y))^x;
  • @Ozil 在实践中,最好使用临时变量交换两个值。 JIT 编译器将识别您在做什么并编写适当的优化代码。此外,任何维护您的代码的人(包括几个月后的您)都将更容易看到意图。

标签: javascript xor


【解决方案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 是修改后的值,而不是初始值。

【讨论】:

  • x ^ (y = y ^ (x = x ^ y));不等于 (y = y ^ (x = x ^ y)) ^ x;这就是你想说的,对吧?
  • @user1589188 总之,是的
猜你喜欢
  • 2019-08-18
  • 2022-01-26
  • 1970-01-01
  • 1970-01-01
  • 2021-01-16
  • 2018-09-26
  • 1970-01-01
  • 2016-01-23
  • 2011-01-19
相关资源
最近更新 更多