为什么 (0 < 5 < 3) 返回 true?
我在 jsfiddle.net 上玩,我很好奇为什么这会返回 true?
if(0 < 5 < 3) {
alert("True");
}
这也是:
if(0 < 5 < 2) {
alert("True");
}
但这不是:
if(0 < 5 < 1) {
alert("True");
}
这个怪癖有用吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(16)
操作顺序导致
(0 < 5 < 3)
在 javascript 中被解释为((0 < 5) < 3)
,从而产生( true < 3)
并且 true 被计为 1,导致返回 true。这也是为什么
(0 < 5 < 1)
返回 false,(0 < 5)
返回 true,被解释为1
,结果为(1 < 1)
。Order of operations causes
(0 < 5 < 3)
to be interpreted in javascript as((0 < 5) < 3)
which produces(true < 3)
and true is counted as 1, causing it to return true.This is also why
(0 < 5 < 1)
returns false,(0 < 5)
returns true, which is interpreted as1
, resulting in(1 < 1)
.我的猜测是因为
0 < 5
为 true,且true < 3
被强制转换为1
3
这是真的。My guess is because
0 < 5
is true, andtrue < 3
gets cast to1 < 3
which is true.可能是因为
true
被假定为1
所以probably because
true
is assumed as1
so因为
true < 3
,因为true == 1
Because
true < 3
, becausetrue == 1
至于你的问题这个怪癖是否有用:我想在某些情况下它可能会有用(如果压缩代码就是你所追求的),但依赖它会(很可能)严重降低代码的可理解性。
这有点像使用后/前增量/减量作为更大表达式的一部分。你能一眼看出这段代码的结果是什么吗?
注意:使用此代码,有时甚至可以根据语言和编译器得到不同的结果。
让自己和下一个人的生活变得轻松是个好主意。阅读你的代码。清楚地写出您真正想要发生的事情,而不是依赖于布尔值的隐式转换等副作用。
As to your question whether this quirk is ever useful: I suppose there could be some case where it would useful (if condensed code is what you are after), but relying on it will (most likely) severely reduce the understandability of your code.
It's kind of like using post/pre increment/decrement as a part of bigger expressions. Can you determine what this code's result is at a glance?
Note: with this code, you can sometimes even get different results depending on the language and compiler.
It's a good idea to make life easy for yourself and the next guy who will read your code. Clearly write out what you actually want to have happen rather then relying on side effects like the implicit conversion of booleans.
问题第二部分的答案“这个怪癖有用吗?”也许不是,正如前面的答案所指出的,如果 true 被强制转换为 1 确实是语言(Javascript)的一个怪癖,但程序员通常不会将 1 和 true(以及 0 和 false)视为同样的事情。
然而,如果你有一个 1 为真、0 为假的心智模型,那么就会产生各种非常有用、强大且直接的布尔技术。例如,您可以直接使用 A > 的结果来增加计数器。 100,如果 A 大于 100,则计数器会递增。这种技术在 Java 中可能被视为怪癖或技巧,但在数组或函数式语言中可能是惯用的。
数组语言 APL 中的一个经典示例是计算数组中(比方说)大于 100 的项目数:
其中,如果 A 是 5 项数组 107 22 256 110 3,则:
产生 5 项布尔数组:
1 0 1 1 0
并对这个布尔结果求和:
得出最终答案:
3
这个问题是一个完美的例子,说明了这种技术非常有用,特别是如果问题被概括为确定 m 个布尔值中的 n 个是否为真。
检查三个布尔值中是否至少有两个是正确
The answer to the second part of the question, "is this quirk ever useful?" is perhaps no, as noted by a previous answer, if it is indeed a quirk of the language (Javascript) that true is cast to 1, but that the programmer does not in general view 1 and true (and 0 and false) as the same thing.
If however you have a mental model of 1 being true and 0 being false, then it leads to all sorts of nice boolean techniques that are extremely useful, powerful, and direct. For example, you could increment a counter directly with the result of A > 100, which would increment the counter if A is greater than 100. This technique might be viewed as a quirk or a trick in Java, but in an array or functional language may be idiomatic.
A classic example in the array language APL would be to count the number of items in an array that are (say) greater than 100:
Where if A is the 5 item array 107 22 256 110 3 then:
yields the 5 item boolean array:
1 0 1 1 0
and summing this boolean result:
yields the final answer:
3
This question is a perfect example of where this technique would be very useful, especially if the problem is generalized to determine if n out of m boolean values are true.
Check if at least two out of three booleans are true
这很容易。
从左到右开始,因此它会评估第一个 0 < 5. 这是真的吗?是的。由于 TRUE=1,因此评估 1 < 3. 由于 1 小于 3,所以这是真的。
现在
0 小于 5 吗?是的。因此,使其为 TRUE,这也意味着 1。现在考虑到这一事实,它的计算结果为 (1 < 1)。 1 小于 1 吗?不,所以它是假的。它必须是平等的。
That's easy.
Start with left to right so it evaluates the first 0 < 5. Is it true? Yes. Since TRUE=1, it evaluates 1 < 3. Since 1 is less than 3 so it's true.
Now with this
Is 0 less than 5? Yes. So make it TRUE which also means 1. Now with that fact in mind, it evaluates to (1 < 1). Is 1 less than 1? No, therefore it's false. It has to be equal.
它是否评估 0<5,当 1<3 为真时,将返回 1 为真?
C# 想要让你做这个“Operator '<'不能应用于“bool”和“int”类型的操作数”
is it evaluating 0<5 which would return 1 for true when 1<3 which is true?
C# want let you do this "Operator '<' cannot be applied to operands of type 'bool' and 'int'"
除了Python之外,CoffeeScript是另一种支持链式比较的语言,因此
3
3 < x < 10
将在 vanilla JS 中转换为(3 < x && x < 10)
In addition to python, CoffeeScript is another language that supports chained comparisons, thus
3 < x < 10
would be converted to(3 < x && x < 10)
in vanilla JS不久前我在 Obj-C 中遇到了这个问题,对此感到非常困惑。我通过做这样的事情得到了我想要的结果:
这当然是错误的,所以你不会得到“真实”的警报。
很高兴我读到了这篇文章,我现在知道为什么了。
I ran into this a little while ago in Obj-C and was very puzzled by it. I got the results I wanted by doing something like this:
Which of course is false so you wouldn't get that "true" alert.
Glad I read this, I now know why.
布尔操作数在数学运算符上运行时返回一个数字。
为了检查这一点,我们
这样做
0 < 5
,返回的boolean(true)与数学运算符(<)运算将返回一个数字。所以它归结为 1<3,返回true
A boolean operand when operated over a math operator returns a number.
to check this we do
So
0 < 5
, the returned boolean(true) operated with math operator(<) will return a number. So it boils to 1<3 which returnstrue
因为 0 小于 5,则返回 true,默认情况下 true 是任何包含 和 的值,可以计算为 1,但仍小于 3,再次返回 true
because 0 is less then 5 then that returns true, and by default true is anything including and can be evaluated to 1 which is still less than 3 which again returns true
我也面临同样的事情。
代码:
在 JavaScript 中,情况 1 和情况 2 都涉及链接比较运算符,并且由于 JavaScript 如何根据运算符优先级和关联性处理它们,这种行为可能看起来违反直觉。
情况 1:
console.log(1 < 2 < 3); // true
(1 < 2) < 3
.1 < 2
为 true(JavaScript 中的true
可以在数字比较中隐式转换为1
)。3
相比,true
被强制转换为数值,从而导致1
1
1
1 3
,这是真的。true
。情况 2:
console.log(3 > 2 > 1); // 假
(3 > 2) > 1
.3> 2
为 true (true
)。1
相比,true
被强制转换为数值,从而得到1 > 1。 1
,这是错误的。false
。由于 JavaScript 的隐式类型强制和比较运算符的从左到右关联性,此行为可能会令人困惑,这在将这些操作链接在一起时可能会导致意外结果。
I also faced the same thing.
code:
In JavaScript, both Case 1 and Case 2 involve chaining comparison operators, and the behavior might seem counterintuitive due to how JavaScript handles them based on operator precedence and associativity.
Case 1:
console.log(1 < 2 < 3); // true
(1 < 2) < 3
.1 < 2
is true (true
in JavaScript can be implicitly converted to1
in numeric comparisons).true
when compared to3
is coerced into numeric values, resulting in1 < 3
, which is true.true
.Case 2:
console.log(3 > 2 > 1); // false
(3 > 2) > 1
.3 > 2
is true (true
).true
when compared to1
is coerced into numeric values, resulting in1 > 1
, which is false.false
.This behavior can be confusing due to JavaScript's implicit type coercion and left-to-right associativity of comparison operators, which can lead to unexpected results when chaining these operations together.
尝试将你的结果表述为 Number()
或尝试这个:
我用 google 搜索了这个,因为我得到
(3 >= 20) //returning true
并且我猜 javascript 正在尝试检查3< /code> 作为布尔值,因为我从
elm.getAttribute();
函数获取此值,而console.log();
以字符串形式打印。try phrasing your results as Number()
or try this:
I googled this because I was getting
(3 >= 20) //returning true
and I guess javascript was trying to check3
as a boolean because I was getting this value from theelm.getAttribute();
function whichconsole.log();
was printing in String form.true == 1 和 false ==0 所以让我们举一个例子,
从左到右开始:
(0 < 5 < 3 ) ---- -->(true < 3 )[ true ==1 ]----->( 1 < 3 ) -----> true
另一个例子
(20 < 1 < 1 ) ------>(false < 1) [false ==0]----->(0 < 1 ) ----- ->真的
true == 1 and false ==0 so let's take one of your examples and start
from left to right :
(0 < 5 < 3 ) ------>(true < 3 )[ true ==1 ]----->( 1 < 3 ) -----> true
another example
(20 < 1 < 1 ) ------>(false < 1) [false ==0]----->(0 < 1 ) ------> true