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

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


所以呢:

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


但这不是:

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


这个怪癖有用吗?

评论

你知道wtfjs.com吗?

哈!不,我从没见过。

啊,隐式类型转换的乐趣。

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

为什么?此外,如果您只能找到需要它的情况,那么任何东西都是有用的。的确,与其他许多人相比,这个人的需求减少了,但是有时甚至很少,而且之间可能相距甚远,而这恰恰是该工作的工具。

#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。 :-)

–森纳
2010年11月3日在16:37

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

– punkrockbuddyholly
10-11-3在16:39



确实,Python是我所知的唯一将此语法视为((0 <5)&&(5 <3))的语言,可能还有其他语言,但我不知道。

–艾伦·盖林斯(Alan Geleynse)
2010年11月3日,16:39

@Alan:Mathematica是另一个例子。

– Joren
2010年11月3日,19:07

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


16年1月9日在21:33

#2 楼

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

评论


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

– erickson
2010年11月4日在18:27

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

–CaffGeek
2010年11月4日在18:49

不用担心埃里克森。我也滥用语义一词。 :)

–玛蒂·乌尔哈克(Mateen Ulhaq)
2010年11月4日在22:48



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

–杰克
2010-11-5 18:33



Sophists一路走...无论如何,回复都是“简洁的”;)

–Arman
2013年6月19日12:11

#3 楼

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

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


#4 楼

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

#5 楼

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

有点像使用后置/前置增量/减量作为较大表达式的一部分。您能否一眼确定该代码的结果是什么?

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


注意:使用此代码,有时甚至可以获得不同的结果,具体取决于语言和编译器。 br />
这是个好主意,让您自己和下一个将阅读您的代码的人的生活变得轻松自在。清楚地写出您实际想要发生的事情,而不要依赖副作用,例如布尔值的隐式转换。

评论


出于好奇,结果是18吗?

– punkrockbuddyholly
2010-11-5 14:12

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

–扎克·约翰逊(Zach Johnson)
2010-11-5 19:27

#6 楼

问题第二部分的答案是:“这个怪癖有用吗?”如先前的回答所述,如果确实是对语言(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吗?不,因此是错误的。它必须相等。

#8 楼

它是否计算0 <5,当1 <3为真时将返回1呢?

C#希望让您执行此操作符“ <'不能应用于'bool'类型的操作数,并且'int'“

评论


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

–Arman
13年6月19日在12:14

#9 楼

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

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


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

#10 楼

除python外,CoffeeScript是另一种支持链式比较的语言,因此3 < x < 10将在香草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)使用数学运算符(<)将返回一个数字。因此它沸腾到1 <3并返回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");
}


我用Google搜索是因为我正在获取(3 >= 20) //returning true,并且我猜Javascript正在尝试将3检查为布尔值,因为我从elm.getAttribute();以字符串形式打印的console.log();函数中获取了此值。