ChatGPT解决这个技术问题 Extra ChatGPT

为什么 (0 < 5 < 3) 返回 true?

我在 jsfiddle.net 中玩耍,我很好奇为什么这会返回 true?

if(0 < 5 < 3) {
    alert("True");
}

这样做也是如此:

if(0 < 5 < 2) {
    alert("True");
}

但这不会:

if(0 < 5 < 1) {
    alert("True");
}

这个怪癖有用吗?

你知道wtfjs.com吗?
哈!不,我以前从未见过。
啊,隐式类型转换的乐趣。
有用过吗?可能是为了混淆视听。 :-)
为什么?此外,如果您只能找到需要它的情况,那么任何东西都是有用的。诚然,与其他许多工具相比,这个工具的需要较少,但有时,尽管它们可能很少,但它可能正是这项工作的工具。

A
Alan Geleynse

操作顺序导致 (0 < 5 < 3) 在 javascript 中被解释为 ((0 < 5) < 3) 产生 (true < 3) 并且 true 被计为 1,导致它返回 true。

这也是为什么(0 < 5 < 1)返回false,(0 < 5)返回true,被解释为1,产生(1 < 1)


而且因为 JavaScript 不是 Python。 :-)
您在我编辑问题以添加 if(0 < 5 < 1) == false 时回答了问题。现在一切都清楚了,谢谢:)
确切地说,Python 是我所知道的唯一一种将此语法视为 ((0 < 5) && (5 < 3)) 的语言,可能还有其他语言,但我不知道它们。
@Alan:Mathematica 是另一个例子。
恕我直言,JavaScript 在尝试将布尔值与数字进行比较时应该引发 TypeError,因为它没有任何意义。
C
CaffGeek

我的猜测是因为 0 < 5 是真的,而 true < 3 被强制转换为 1 < 3 这是真的。


这里没有选角。强制转换是一个运算符,程序员使用它来显式检查类型。这是从布尔值到整数的隐式转换。
@erickson,真的……我们需要在这里挂断语义吗?
不要担心埃里克森。我也误用了语义这个词。 :)
无论如何,正确的术语是强制。是的,埃里克森的绝对确定性是部分错误的。在任何情况下,强制转换都是一种强制转换,如果通常(但这只是一种约定)您使用“强制转换”这个词来表示显式类型转换。类型转换 == 类型转换。
一直是诡辩者......无论如何,回复都是“简洁”的好;)
J
Jack

可能是因为 true 被假定为 1 所以

0 < 5 < 3  -->  true < 3 -->  1 < 3  --> true

H
Harmen

因为true < 3,因为true == 1


Z
Zach Johnson

至于你的问题,这个怪癖是否有用:我想在某些情况下它会很有用(如果压缩代码是你所追求的),但依赖它(很可能)会严重降低你的代码的可理解性。

这有点像使用 post/pre 递增/递减作为更大表达式的一部分。你能一眼确定这段代码的结果是什么吗?

int x = 5;
int result = ++x + x++ + --x;

注意:使用此代码,您有时甚至可以获得不同的结果,具体取决于语言和编译器。

让你自己和下一个阅读你的代码的人更轻松是个好主意。清楚地写出您真正想要发生的事情,而不是依赖诸如布尔值的隐式转换之类的副作用。


出于好奇,result 18 岁吗?
@MrMisterMan:我不确定 Javascript,但在 Java 和 C# 中,计算保证从左到右,结果确实是 18。在某些语言中,例如 C 和 C++,不能保证它会是从左到右进行评估,根据编译器添加的优化,您最终可能会得到不同的结果。
C
Community

问题第二部分的答案,“这个怪癖有用吗?”可能不是,正如前面的答案所指出的那样,如果确实是语言(Javascript)的一个怪癖,将 true 强制转换为 1,但程序员通常不会将 1 和 true(以及 0 和 false)视为一样。

但是,如果您有一个 1 为真,0 为假的心智模型,那么它会导致各种非常有用、强大且直接的漂亮布尔技术。例如,您可以使用 A > 100 的结果直接增加一个计数器,如果 A 大于 100,这将增加计数器。这种技术在 Java 中可能被视为一种怪癖或技巧,但在数组或函数语言中可能是惯用语。

数组语言 APL 中的一个经典示例是计算数组中(例如)大于 100 的项目数:

+/A>100

如果 A 是 5 项数组 107 22 256 110 3 那么:

A>100

产生 5 项布尔数组:

1 0 1 1 0

并对这个布尔结果求和:

+/1 0 1 1 0

产生最终答案:

3

This question 是该技术非常有用的一个完美示例,特别是如果问题被概括为确定 m 个布尔值中的 n 个是否为真。

Check if at least two out of three booleans are true


n
netrox

这很容易。

(0 < 5 < 3)

从左到右开始,因此它评估第一个 0 < 5。是真的吗?是的。由于 TRUE=1,它评估 1 < 3。因为 1 小于 3,所以它是真的。

现在有了这个

 (0 < 5 < 1)

0小于5吗?是的。所以让它 TRUE 这也意味着 1。现在考虑到这个事实,它的计算结果为 (1 < 1)。 1 小于 1 吗?不,因此它是错误的。它必须是平等的。


D
David

当 1<3 为真时,它是否评估 0<5 将返回 1 为真?

C#想让你这样做“运算符'<'不能应用于'bool'和'int'类型的操作数”


有时我会怀念 C# 在动态语言中的严格性。
H
Hippocrates

我不久前在 Obj-C 中遇到了这个问题,对此感到非常困惑。通过执行以下操作,我得到了想要的结果:

if(0 < 5  && 5 < 3) {
alert("True");}

这当然是错误的,所以你不会得到那个“真实”的警报。很高兴我读到了这篇文章,我现在知道为什么了。


H
Hippocrates

除了 python,CoffeeScript 是另一种支持链式比较的语言,因此 3 < x < 10 将在 vanilla JS 中转换为 (3 < x && x < 10)


M
Michał Perłakowski
0 < 5 < 3 
==> ( ( 0 < 5 ) < 3 )
==> true < 3
==> 1 < 3
==> true

R
Rajkamal Subramanian

对数学运算符进行操作时,布尔操作数返回一个数字。为了检查这一点,我们做

true + 1  which gives you 2.

所以0 < 5,用数学运算符(<)操作返回的布尔值(真)将返回一个数字。所以它沸腾到 1<3 返回 true


n
ndotie

因为 0 小于 5 则返回 true,并且默认情况下 true 是任何包括并且可以评估为 1 仍然小于 3 再次返回 true


S
SwiftNinjaPro

尝试将结果表述为 Number()

if(Number(0) < Number(5) < Number(3)) {
    alert("True");
}

或试试这个:

if(Number(0) < Number(5) && Number(5) < Number(3)) {
    alert("True");
}

我用谷歌搜索了这个,因为我得到了 (3 >= 20) //returning true,我猜 javascript 正试图检查 3 作为布尔值,因为我从 console.log(); 以字符串形式打印的 elm.getAttribute(); 函数获取这个值。