为啥 (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 < 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,因为它没有任何意义。【参考方案2】:
我的猜测是因为0 < 5
是真的,而true < 3
被强制转换为1 < 3
这是真的。
【讨论】:
这里没有选角。强制转换是一个运算符,程序员使用它显式检查一个类型。这是从布尔值到整数的隐式转换。 @erickson,真的……我们需要在这里关注语义吗? 别担心埃里克森。我也误用了语义这个词。 :) 无论如何,正确的术语是强制。是的,埃里克森的绝对确定性是部分错误的。在任何情况下,强制转换都是一种强制转换,如果通常(但这只是一种约定)您使用“强制转换”这个词来表示显式类型转换。类型转换 == 类型转换。 一直是诡辩者......无论如何,回复都是“简洁”的好;)【参考方案3】:可能是因为true
被假定为1
所以
0 < 5 < 3 --> true < 3 --> 1 < 3 --> true
【讨论】:
【参考方案4】:因为true < 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 < x < 10
在 vanilla JS 中会被转换为 (3 < x && x < 10)
【讨论】:
【参考方案11】:0 < 5 < 3
==> ( ( 0 < 5 ) < 3 )
==> true < 3
==> 1 < 3
==> true
【讨论】:
【参考方案12】:对数学运算符进行运算时,布尔操作数返回一个数字。 要检查这一点,我们会做
true + 1 which gives you 2.
所以0 < 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 >= 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);