为啥 (0 < 5 < 3) 返回 true?

Posted

技术标签:

【中文标题】为啥 (0 < 5 < 3) 返回 true?【英文标题】:Why does (0 < 5 < 3) return true?为什么 (0 < 5 < 3) 返回 true? 【发布时间】:2011-05-04 14:35:56 【问题描述】:

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

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

也是这样:

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

但这不是:

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

这个怪癖有用吗?

【问题讨论】:

你知道wtfjs.com 吗? 哈!不,我以前从未见过。 啊,隐式类型转换的乐趣。 有用吗?可能是为了混淆视听。 :-) 为什么?此外,如果您只能找到需要它的情况,anything 也会很有用。诚然,与其他许多工具相比,这个工具的使用频率较低,但有时,尽管它们可能很少而且相距甚远,但它可能正是完成这项工作的工具。 【参考方案1】:

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

这也是为什么(0 &lt; 5 &lt; 1)返回false,(0 &lt; 5)返回true,解释为1,导致(1 &lt; 1)

【讨论】:

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

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

【讨论】:

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

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

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

【讨论】:

【参考方案4】:

因为true &lt; 3,因为true == 1

【讨论】:

【参考方案5】:

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

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

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

注意:使用此代码,有时甚至可以根据语言和编译器获得不同的结果。

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

【讨论】:

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

问题第二部分的答案“这个怪癖有用吗?”可能不是,正如前面的答案所指出的,如果确实是语言(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

【讨论】:

【参考方案7】:

这很容易。

(0 < 5 < 3)

从左到右开始计算第一个 0

现在有了这个

 (0 < 5 < 1)

0 是否小于 5?是的。所以让它 TRUE 这也意味着 1。现在考虑到这个事实,它的计算结果为 (1

【讨论】:

【参考方案8】:

当 1

C#想让你这样做“运算符'

【讨论】:

有时我怀念 C# 在动态语言中的严格性。【参考方案9】:

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

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

这当然是错误的,因此您不会收到“真实”警报。 很高兴我读到了这篇文章,我现在知道为什么了。

【讨论】:

【参考方案10】:

除了 python 之外,CoffeeScript 是另一种支持链式比较的语言,因此 3 &lt; x &lt; 10 在 vanilla JS 中会被转换为 (3 &lt; x &amp;&amp; x &lt; 10)

【讨论】:

【参考方案11】:
0 < 5 < 3 
==> ( ( 0 < 5 ) < 3 )
==> true < 3
==> 1 < 3
==> true

【讨论】:

【参考方案12】:

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

true + 1  which gives you 2.

所以0 &lt; 5,用数学运算符(true

【讨论】:

【参考方案13】:

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

【讨论】:

【参考方案14】:

尝试将结果表述为 Number()

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

或者试试这个:

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

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

【讨论】:

以上是关于为啥 (0 < 5 < 3) 返回 true?的主要内容,如果未能解决你的问题,请参考以下文章

为啥使用 IAsyncEnumerable 比返回 async/await Task<T> 慢?

在java中t.getClass为啥返回的是Class<gt;而不是Class<T>

为啥 WCF 会返回 myObject[] 而不是 List<T> 像我期望的那样?

为啥 List<T> 在 .NET 4.5 中实现 IReadOnlyList<T>?

为啥 List<T> 的“索引超出范围”异常,但数组却没有?

这个程序为啥可以延时一秒: while(t[0].ti_sec==s&&t[0].ti_min==m&&t[0].ti_hour==h) gettime(t);