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

pun*_*lly 345 javascript boolean-logic compare operators

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

if(0 < 5 < 3) {
    alert("True");
}
Run Code Online (Sandbox Code Playgroud)

这样做:

if(0 < 5 < 2) {
    alert("True");
}
Run Code Online (Sandbox Code Playgroud)

但这不是:

if(0 < 5 < 1) {
    alert("True");
}
Run Code Online (Sandbox Code Playgroud)

这个怪癖是否有用?

Ala*_*nse 436

操作顺序导致(0 < 5 < 3)在javascript中解释为((0 < 5) < 3)生成(true < 3)并且true被计为1,从而使其返回true.

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

  • 而且因为JavaScript不是Python.:-) (157认同)
  • 确切地说,Python是我所知道的唯一一种将这种语法视为`((0 <5)&&(5 <3))`的语言,可能有其他但我不知道它们. (27认同)
  • @Alan:Mathematica是另一个例子. (18认同)
  • Perl 6开始. (5认同)
  • 恕我直言,JavaScript 在尝试将布尔值与数字进行比较时应该引发 TypeError,因为它没有意义。 (2认同)

Caf*_*eek 63

我的猜测是因为0 < 5是真的,并且true < 3被投射到了1 < 3真实.

  • 无论如何,正确的术语是_coercion_.是的,erickson部分错误,这是绝对的确定性.强制在任何情况下都是一种强制转换,如果通常(但它只是一种惯例),你使用"强制转换"这个词来表达明确的类型转换.类型转换==类型转换. (9认同)
  • 这里没有铸造.强制转换是一个运算符,程序员使用它来*显式*检查类型.这是*隐式*从布尔值转换为整数. (7认同)
  • @erickson,真的......我们需要在这里挂上语义吗? (4认同)
  • 不要担心埃里克森.我也误用了语义这个词.:) (2认同)

Jac*_*ack 21

可能是因为true假设1如此

0 < 5 < 3  -->  true < 3 -->  1 < 3  --> true
Run Code Online (Sandbox Code Playgroud)


Har*_*men 17

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


Zac*_*son 10

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

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

int x = 5;
int result = ++x + x++ + --x;
Run Code Online (Sandbox Code Playgroud)

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

让自己和下一个阅读代码的人变得轻松生活是一个好主意.清楚地写出你真正想要发生的事情而不是依赖于隐含的布尔转换等副作用.

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

小智 9

对问题第二部分的回答是"这个怪癖是否有用?" 也许没有,正如之前的回答所指出的,如果确实是语言(Javascript)的怪癖,则将true强制转换为1,但程序员通常不会将1和true(以及0和false)视为一样.

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

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

+/A>100
Run Code Online (Sandbox Code Playgroud)

如果A是5项阵列107 22 256 110 3那么:

A>100
Run Code Online (Sandbox Code Playgroud)

产生5项布尔数组:

1 0 1 1 0

并总结这个布尔结果:

+/1 0 1 1 0
Run Code Online (Sandbox Code Playgroud)

得出最终答案:

3

这个问题是这个技术非常有用的一个很好的例子,特别是如果问题被推广以确定m个布尔值中的n是否为真.

检查三个布尔值中是否至少有两个是真的


net*_*rox 7

这很简单.

(0 < 5 < 3)
Run Code Online (Sandbox Code Playgroud)

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

现在有了这个

 (0 < 5 < 1)
Run Code Online (Sandbox Code Playgroud)

0小于5?是.因此,将其设为TRUE,这也意味着1.现在考虑到这一事实,它的评估结果为(1 <1).1小于1?不,因此它是假的.它必须是平等的.