This question already has an answer here:
这个问题在这里已有答案:
- In JavaScript, why is “0” equal to false, but when tested by 'if' it is not false by itself? 9 answers
在JavaScript中,为什么“0”等于false,但是当'if'测试时它本身并不是假的? 9个答案
I came across a strange issue with boolean operation in my web application. I have a service that responds with 1
and 0
for true
and false
. The REST API (internal one) that I call, sends only this output:
我在Web应用程序中遇到了一个布尔运算的奇怪问题。我有一个响应1和0的服务,用于true和false。我调用的REST API(内部)仅发送此输出:
GET /stuff/id/5
0
GET /stuff/id/7
1
Based on the above output from the server, I use a toggle switch in the front end to check make it switch on or off. The code that makes it is:
根据服务器的上述输出,我使用前端的拨动开关来检查它是否打开或关闭。它的代码是:
$(this).find(".toggle").toggles({
"on": requestContent
});
I do understand that sometimes, 1
and 0
might not be interpreted as boolean true or false, so I planned to use !!
to force them to get converted into true
and false
.
我明白有时候,1和0可能不会被解释为布尔值true或false,所以我打算用!!强迫他们转变为真假。
$(this).find(".toggle").toggles({
"on": !!requestContent
});
But still, to my dismay, it shows all the switches in the ON position, than the right way. Somehow it is getting converted to only true
for both the values of 1
and 0
.
但令人沮丧的是,它显示了ON位置的所有开关,而不是正确的方式。不知何故,对于1和0的值,它只被转换为true。
I have even tried to make a mock version of the server call and my front end here, which exactly replicates the issue:
我甚至试图在这里制作服务器调用的模拟版本和我的前端,这完全复制了这个问题:
$(function () {
// Mimicking the HTTP Response.
var states = ["1", "0", "0", "1", "1"];
// This loop loops through all the values and sets the state of the switch.
$('.toggle').each(function (i) {
$(this).toggles({
"on": !!states[i]
});
});
});
body {background-color: #f5f5f5;}
ul, li {margin: 0; padding: 0; list-style: none;}
ul {width: 150px; margin: auto; background-color: #fff; padding: 10px; border-radius: 3px; border: 1px solid #eee;}
ul li {padding: 10px;}
ul li span,
ul li .toggle {width: 50px; display: inline-block; vertical-align: middle;}
ul li span {width: 75px; line-height: 1;}
<link rel="stylesheet" href="https://cdn.rawgit.com/simontabor/jquery-toggles/master/css/toggles-full.css" />
<script src="https://code.jquery.com/jquery-2.2.4.js"></script>
<script src="https://cdn.rawgit.com/simontabor/jquery-toggles/master/toggles.min.js"></script>
<ul>
<li>
<span>Item 1</span>
<div class="toggle toggle-light"></div>
</li>
<li>
<span>Item 2</span>
<div class="toggle toggle-light"></div>
</li>
<li>
<span>Item 3</span>
<div class="toggle toggle-light"></div>
</li>
<li>
<span>Item 4</span>
<div class="toggle toggle-light"></div>
</li>
<li>
<span>Item 5</span>
<div class="toggle toggle-light"></div>
</li>
</ul>
As you can see, all the happens is even !!0
returns true
. How do I solve this? What's the mystery behind this?
如你所见,所有发生的事情都是!! 0返回true。我该如何解决这个问题?这背后的秘密是什么?
1 个解决方案
#1
2
The main problem is that the way JavaScript type-casts is totally different. In other words, after an hour of debugging, I found that the issue was with the way JavaScript treats the strings as truthy values.
主要问题是JavaScript类型转换的方式完全不同。换句话说,经过一个小时的调试后,我发现问题在于JavaScript将字符串视为truthy值的方式。
When the server responds, the response is always given as string
type. Strings with a 0
(which is actually "0"
) need to be type-casted into boolean false
. Instead, JavaScript takes it as a non-empty string
and finds it as truthy value.
当服务器响应时,响应始终以字符串类型给出。带有0(实际上是“0”)的字符串需要被类型转换为布尔值false。相反,JavaScript将其视为非空字符串,并将其视为真正的值。
Let's consider this code that I ran on the console.
让我们考虑一下我在控制台上运行的代码。
» if ("0") "Yes"; else "No";
« "Yes"
Here, we could clearly see that the "0"
string value is treated as a true
or correctly, truthy value. So when the non-empty strings are not considered as false
, a string with "0"
is also not considered false
.
在这里,我们可以清楚地看到“0”字符串值被视为真实或正确,真实的值。因此,当非空字符串不被视为false时,具有“0”的字符串也不被视为false。
Work-arounds
One of the best way to get around this is using the comparison with 0
. Consider the following instruction on the console:
解决此问题的最佳方法之一是使用与0的比较。请在控制台上考虑以下说明:
» "0" == 0
« true
» !!"0"
« true
To check the correct value, the comparison operator helps us in comparing string "0"
with integral 0
and it works. At the same time, it is freaking out that the type-casting of string "0"
gives you true
.
为了检查正确的值,比较运算符帮助我们比较字符串“0”和积分0,它可以工作。与此同时,字符串“0”的类型转换为您提供了真实的结果。
The second method would be using parseInt()
. This should be used only when we are triple sure that the output is an integral value and nothing else. We can also add isNaN()
as an exception handling mechanism, but that would be overkill.
第二种方法是使用parseInt()。只有当我们确定输出是一个整数值而没有别的时候才应该使用它。我们还可以添加isNaN()作为异常处理机制,但这样做会有点过分。
» if (parseInt("0")) "Yes"; else "No";
« "No"
Solution
Right now, the best solution is to use parseInt()
, as I am definitely sure the service will not return any other value other than 1
or 0
.
现在,最好的解决方案是使用parseInt(),因为我绝对肯定服务不会返回除1或0以外的任何其他值。
$(function () {
// Mimicking the HTTP Response.
var states = ["1", "0", "0", "1", "1"];
// This loop loops through all the values and sets the state of the switch.
$('.toggle').each(function (i) {
$(this).toggles({
// Now this works perfectly! ;)
"on": parseInt(states[i])
});
});
});
body {background-color: #f5f5f5;}
ul, li {margin: 0; padding: 0; list-style: none;}
ul {width: 150px; margin: auto; background-color: #fff; padding: 10px; border-radius: 3px; border: 1px solid #eee;}
ul li {padding: 10px;}
ul li span,
ul li .toggle {width: 50px; display: inline-block; vertical-align: middle;}
ul li span {width: 75px; line-height: 1;}
<link rel="stylesheet" href="https://cdn.rawgit.com/simontabor/jquery-toggles/master/css/toggles-full.css" />
<script src="https://code.jquery.com/jquery-2.2.4.js"></script>
<script src="https://cdn.rawgit.com/simontabor/jquery-toggles/master/toggles.min.js"></script>
<ul>
<li>
<span>Item 1</span>
<div class="toggle toggle-light"></div>
</li>
<li>
<span>Item 2</span>
<div class="toggle toggle-light"></div>
</li>
<li>
<span>Item 3</span>
<div class="toggle toggle-light"></div>
</li>
<li>
<span>Item 4</span>
<div class="toggle toggle-light"></div>
</li>
<li>
<span>Item 5</span>
<div class="toggle toggle-light"></div>
</li>
</ul>
I have asked and answered my own question. If anyone has a better explanation (with sources), or a different work-around, please post another answer.
我问过并回答了我自己的问题。如果有人有更好的解释(有消息来源)或不同的解决方法,请发布另一个答案。
#1
2
The main problem is that the way JavaScript type-casts is totally different. In other words, after an hour of debugging, I found that the issue was with the way JavaScript treats the strings as truthy values.
主要问题是JavaScript类型转换的方式完全不同。换句话说,经过一个小时的调试后,我发现问题在于JavaScript将字符串视为truthy值的方式。
When the server responds, the response is always given as string
type. Strings with a 0
(which is actually "0"
) need to be type-casted into boolean false
. Instead, JavaScript takes it as a non-empty string
and finds it as truthy value.
当服务器响应时,响应始终以字符串类型给出。带有0(实际上是“0”)的字符串需要被类型转换为布尔值false。相反,JavaScript将其视为非空字符串,并将其视为真正的值。
Let's consider this code that I ran on the console.
让我们考虑一下我在控制台上运行的代码。
» if ("0") "Yes"; else "No";
« "Yes"
Here, we could clearly see that the "0"
string value is treated as a true
or correctly, truthy value. So when the non-empty strings are not considered as false
, a string with "0"
is also not considered false
.
在这里,我们可以清楚地看到“0”字符串值被视为真实或正确,真实的值。因此,当非空字符串不被视为false时,具有“0”的字符串也不被视为false。
Work-arounds
One of the best way to get around this is using the comparison with 0
. Consider the following instruction on the console:
解决此问题的最佳方法之一是使用与0的比较。请在控制台上考虑以下说明:
» "0" == 0
« true
» !!"0"
« true
To check the correct value, the comparison operator helps us in comparing string "0"
with integral 0
and it works. At the same time, it is freaking out that the type-casting of string "0"
gives you true
.
为了检查正确的值,比较运算符帮助我们比较字符串“0”和积分0,它可以工作。与此同时,字符串“0”的类型转换为您提供了真实的结果。
The second method would be using parseInt()
. This should be used only when we are triple sure that the output is an integral value and nothing else. We can also add isNaN()
as an exception handling mechanism, but that would be overkill.
第二种方法是使用parseInt()。只有当我们确定输出是一个整数值而没有别的时候才应该使用它。我们还可以添加isNaN()作为异常处理机制,但这样做会有点过分。
» if (parseInt("0")) "Yes"; else "No";
« "No"
Solution
Right now, the best solution is to use parseInt()
, as I am definitely sure the service will not return any other value other than 1
or 0
.
现在,最好的解决方案是使用parseInt(),因为我绝对肯定服务不会返回除1或0以外的任何其他值。
$(function () {
// Mimicking the HTTP Response.
var states = ["1", "0", "0", "1", "1"];
// This loop loops through all the values and sets the state of the switch.
$('.toggle').each(function (i) {
$(this).toggles({
// Now this works perfectly! ;)
"on": parseInt(states[i])
});
});
});
body {background-color: #f5f5f5;}
ul, li {margin: 0; padding: 0; list-style: none;}
ul {width: 150px; margin: auto; background-color: #fff; padding: 10px; border-radius: 3px; border: 1px solid #eee;}
ul li {padding: 10px;}
ul li span,
ul li .toggle {width: 50px; display: inline-block; vertical-align: middle;}
ul li span {width: 75px; line-height: 1;}
<link rel="stylesheet" href="https://cdn.rawgit.com/simontabor/jquery-toggles/master/css/toggles-full.css" />
<script src="https://code.jquery.com/jquery-2.2.4.js"></script>
<script src="https://cdn.rawgit.com/simontabor/jquery-toggles/master/toggles.min.js"></script>
<ul>
<li>
<span>Item 1</span>
<div class="toggle toggle-light"></div>
</li>
<li>
<span>Item 2</span>
<div class="toggle toggle-light"></div>
</li>
<li>
<span>Item 3</span>
<div class="toggle toggle-light"></div>
</li>
<li>
<span>Item 4</span>
<div class="toggle toggle-light"></div>
</li>
<li>
<span>Item 5</span>
<div class="toggle toggle-light"></div>
</li>
</ul>
I have asked and answered my own question. If anyone has a better explanation (with sources), or a different work-around, please post another answer.
我问过并回答了我自己的问题。如果有人有更好的解释(有消息来源)或不同的解决方法,请发布另一个答案。