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


348

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

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

这样:

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

但这不是:

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

这个怪癖有用吗?


12
您知道wtfjs.com吗?
哈曼2010年

1
哈!不,我从未见过。
punkrockbuddyholly

啊,隐式类型转换的乐趣。
约尔格W¯¯米塔格

4
有用吗?可能造成混淆。:-)
Icode4food

为什么?另外,如果您只能找到需要它的情况,那么任何东西都是有用的。的确,与其他许多项目相比,此项目的使用频率较低,但是有时甚至是很短的时间,而这可能正是这项工作的工具。
临时用户名

Answers:


440

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

这也是为什么(0 < 5 < 1)返回false,(0 < 5)返回true,为什么将其解释为1,从而导致的原因(1 < 1)


158
而且因为JavaScript不是Python。:-)
rsenna

1
在我编辑问题以添加时,您回答了if(0 < 5 < 1) == false。现在一切都清楚了,谢谢:)
punkrockbuddyholly

28
确实,Python是我所知的唯一将这种语法视为的语言((0 < 5) && (5 < 3)),可能还有其他语言,但我不知道。
艾伦·盖林斯

18
@Alan:Mathematica是另一个例子。
Joren

2
恕我直言,JavaScript在尝试将布尔值与数字进行比较时应引发TypeError,因为这没有任何意义。
米哈尔Perłakowski

63

我的猜测是因为 0 < 5是正确的,并且true < 3被强制转换1 < 3为正确的。


7
这里没有演员。强制转换是一种运算符,程序员用于显式检查类型。这是从布尔值到整数的隐式转换。
erickson

4
@erickson,真的...我们需要在这里挂断语义吗?
CaffGeek

2
不用担心埃里克森。我也滥用语义一词。:)
Mateen Ulhaq 2010年

9
无论如何,正确的用语是胁迫。是的,埃里克森的绝对确定性在一定程度上是错误的。在任何情况下,强制转换也是一种强制类型转换,即使通常(但仅是约定)您使用“ cast”一词来表示显式类型转换。类型转换==类型转换。
杰克2010年

1
Sophists一路走...无论如何,答复都是'laconically'不错的;)
Arman McHitarian 2013年

21

可能是因为true假设1如此

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


10

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

有点像使用后/前递增/递减作为较大表达式的一部分。您能一眼确定此代码的结果吗?

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

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

一个好主意是让自己和下一个将阅读您的代码的人都过得轻松。清楚地写出您实际想要发生的事情,而不要依赖副作用,例如布尔值的隐式转换。


出于好奇,是result18岁吗?
punkrockbuddyholly

5
@MrMisterMan:我不确定Javascript,但是在Java和C#中保证评估是从左到右的,结果的确是18。在某些语言中,例如C和C ++,不能保证它会从左到右进行评估,最终可能会得到不同的结果,具体取决于编译器添加的优化。
扎克·约翰逊

9

问题第二部分的答案是“这个怪癖有用吗?” 如先前的回答所述,如果确实是对语言(J​​avascript)的怪癖,则将true强制转换为1,但程序员通常不将1和true(以及0和false)视为是真话。一样。

但是,如果您有一个心理模型,即1为true,0为false,那么它将导致产生各种非常有用,强大且直接的布尔技术。例如,您可以使用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

这个问题是该技术在哪里非常有用的一个完美示例,特别是如果该问题被普遍确定为m个布尔值中的n个是否为真。

检查三个布尔中至少两个是否为真


7

这很容易。

(0 < 5 < 3)

从左到右开始,因此它会评估第一个0 <5。是否正确?是。由于TRUE = 1,因此其计算结果为1 <3。由于1小于3,因此为true。

现在有了这个

 (0 < 5 < 1)

0小于5吗?是。因此将其设置为TRUE,这也意味着1。现在牢记这一事实,其求值为(1 <1)。1小于1吗?不,因此是错误的。它必须相等。


4

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

C#希望您执行此操作:“运算符'<'无法应用于类型为'bool'和'int'的操作数”


有时我想念C#对动态语言的严格要求。
Arman McHitarian

4

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

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

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


4

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



1

当对数学运算符进行运算时,布尔操作数将返回数字。检查一下我们

true + 1  which gives you 2.

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


1

因为0小于5然后返回true,并且默认情况下为true包括任何内容,并且可以求值为1,但仍然小于3再次返回true


0

尝试将结果表示为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();

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.