我有一个存储false或true的变量,但我需要分别存储0或1。我该怎么做呢?
false
true
0
1
使用一元+运算符,它将其操作数转换为数字。
+
+ true; // 1 + false; // 0
当然,请注意,您仍然应该在服务器端清除数据,因为用户可以将任何数据发送到您的服务器,而不管客户端代码说了什么。
一元+操作符将处理这些:
var test = true; // +test === 1 test = false; // +test === 0
您自然希望在存储它之前在服务器上检查它,因此在服务器上执行此操作可能是一个更明智的地方。
Javascript有一个三元操作符,你可以使用:
var i = result ? 1 : 0;
我今天偶然发现了这条近路。
~ ~(真正的)
~ ~(假)
比我聪明得多的人可以解释:
http://james.padolsey.com/javascript/double-bitwise-not/
我只是在我写的一些代码中处理这个问题。我的解决方案是使用一个位和。
var j = bool & 1;
处理常量问题的一个更快的方法是创建一个函数。它更便于其他人阅读,更便于在维护阶段理解,并消除了编写错误的可能性。
function toInt( val ) { return val & 1; } var j = toInt(bool);
编辑- 2014年9月10日
在Chrome中,由于某些原因,使用三元操作符和相同的to操作符的转换速度更快。不知道为什么它更快,但我认为这是某种低级优化,在某个地方是有意义的。
var j = boolValue === true ? 1 : 0;
自己测试:http://jsperf.com/boolean-int-conversion/2
在FireFox和Internet Explorer中,使用我发布的版本通常更快。
编辑- 2017年7月14日
好吧,我不会告诉你该用哪个,不该用哪个。每个该死的浏览器都在用每个方法进行操作的速度上下波动。Chrome在某一时刻实际上有位&版本做得比其他版本好,但突然变得更糟了。我不知道他们在做什么,所以我就把它留给谁管。几乎没有任何理由去关心这样的手术能多快完成。即使在手机平台上,这也是一项毫无意义的操作。
此外,这里有一个新的方法来添加一个“toInt”原型,不能被覆盖。
Object.defineProperty(Boolean.prototype, "toInt", { value: function() { return this & 1; }});
我更喜欢使用数函数。它接受一个对象并将其转换为一个数字。
例子:
var myFalseBool = false; var myTrueBool = true; var myFalseInt = Number(myFalseBool); console.log(myFalseInt === 0); var myTrueInt = Number(myTrueBool); console.log(myTrueInt === 1);
你可以在jsFiddle中测试它。
您可以通过简单地扩展布尔原型来做到这一点
Boolean.prototype.intval = function(){return ~~this}
不太容易理解那里发生了什么所以另一个版本会是
Boolean.prototype.intval = function(){return (this == true)?1:0}
你可以做一些事情
document.write(true.intval());
当我使用布尔值存储条件时,我经常将它们转换为位域,在这种情况下,我最终使用了原型函数的扩展版本
Boolean.prototype.intval = function(places) { places = ('undefined' == typeof(places))?0:places; return (~~this) << places }
你可以这样做
document.write(true.intval(2))
它的输出是4。
依我看,最好的解决办法是:
fooBar | 0
这在asm.js中用于强制整型。
我对所有建议的答案创建了JSperf比较。
TL;DR -当前所有浏览器的最佳选择是:
val | 0;
.
更新:
现在它们似乎都是一样的,除了Number()函数是最慢的,而最好的是val === true ? 1 : 0;。
Number()
val === true ? 1 : 0;
你也可以添加0,使用shift运算符或xor:
val + 0; val ^ 0; val >> 0; val >>> 0; val << 0;
这些答案和其他答案的速度相似。
当JavaScript期望一个数字值但接收到一个布尔值时,它会将该布尔值转换为一个数字:true和false分别转换为1和0。所以你可以利用这个;
var t = true; var f = false; console.log(t*1); // t*1 === 1 console.log(f*1); // f*1 === 0 console.log(+t); // 0+t === 1 or shortened to +t === 1 console.log(+f); //0+f === 0 or shortened to +f === 0
进一步阅读Javascript权威指南第3.8章的类型转换。
输入的方法是:
Number(true) // 1 Number(false) // 0
let integerVariable = booleanVariable * 1;
我已经测试了所有这些例子,我做了一个基准测试,最后我建议你选择较短的一个,它不会影响性能。
运行在Ubuntu服务器14.04,nodejs v8.12.0 - 26/10/18
let i = 0; console.time("TRUE test1") i=0; for(;i<100000000;i=i+1){ true ? 1 : 0; } console.timeEnd("TRUE test1") console.time("FALSE test2") i=0; for(;i<100000000;i=i+1){ false ? 1 : 0; } console.timeEnd("FALSE test2") console.log("----------------------------") console.time("TRUE test1.1") i=0; for(;i<100000000;i=i+1){ true === true ? 1 : 0; } console.timeEnd("TRUE test1.1") console.time("FALSE test2.1") i=0; for(;i<100000000;i=i+1){ false === true ? 1 : 0; } console.timeEnd("FALSE test2.1") console.log("----------------------------") console.time("TRUE test3") i=0; for(;i<100000000;i=i+1){ true | 0; } console.timeEnd("TRUE test3") console.time("FALSE test4") i=0; for(;i<100000000;i=i+1){ false | 0; } console.timeEnd("FALSE test4") console.log("----------------------------") console.time("TRUE test5") i=0; for(;i<100000000;i=i+1){ true * 1; } console.timeEnd("TRUE test5") console.time("FALSE test6") i=0; for(;i<100000000;i=i+1){ false * 1; } console.timeEnd("FALSE test6") console.log("----------------------------") console.time("TRUE test7") i=0; for(;i<100000000;i=i+1){ true & 1; } console.timeEnd("TRUE test7") console.time("FALSE test8") i=0; for(;i<100000000;i=i+1){ false & 1; } console.timeEnd("FALSE test8") console.log("----------------------------") console.time("TRUE test9") i=0; for(;i<100000000;i=i+1){ +true; } console.timeEnd("TRUE test9") console.time("FALSE test10") i=0; for(;i<100000000;i=i+1){ +false; } console.timeEnd("FALSE test10") console.log("----------------------------") console.time("TRUE test9.1") i=0; for(;i<100000000;i=i+1){ 0+true; } console.timeEnd("TRUE test9.1") console.time("FALSE test10.1") i=0; for(;i<100000000;i=i+1){ 0+false; } console.timeEnd("FALSE test10.1") console.log("----------------------------") console.time("TRUE test9.2") i=0; for(;i<100000000;i=i+1){ -true*-1; } console.timeEnd("TRUE test9.2") console.time("FALSE test10.2") i=0; for(;i<100000000;i=i+1){ -false*-1; } console.timeEnd("FALSE test10.2") console.log("----------------------------") console.time("TRUE test9.3") i=0; for(;i<100000000;i=i+1){ true-0; } console.timeEnd("TRUE test9.3") console.time("FALSE test10.3") i=0; for(;i<100000000;i=i+1){ false-0; } console.timeEnd("FALSE test10.3") console.log("----------------------------") console.time("TRUE test11") i=0; for(;i<100000000;i=i+1){ Number(true); } console.timeEnd("TRUE test11") console.time("FALSE test12") i=0; for(;i<100000000;i=i+1){ Number(false); } console.timeEnd("FALSE test12") console.log("----------------------------") console.time("TRUE test13") i=0; for(;i<100000000;i=i+1){ true + 0; } console.timeEnd("TRUE test13") console.time("FALSE test14") i=0; for(;i<100000000;i=i+1){ false + 0; } console.timeEnd("FALSE test14") console.log("----------------------------") console.time("TRUE test15") i=0; for(;i<100000000;i=i+1){ true ^ 0; } console.timeEnd("TRUE test15") console.time("FALSE test16") i=0; for(;i<100000000;i=i+1){ false ^ 0; } console.timeEnd("FALSE test16") console.log("----------------------------") console.time("TRUE test17") i=0; for(;i<100000000;i=i+1){ true ^ 0; } console.timeEnd("TRUE test17") console.time("FALSE test18") i=0; for(;i<100000000;i=i+1){ false ^ 0; } console.timeEnd("FALSE test18") console.log("----------------------------") console.time("TRUE test19") i=0; for(;i<100000000;i=i+1){ true >> 0; } console.timeEnd("TRUE test19") console.time("FALSE test20") i=0; for(;i<100000000;i=i+1){ false >> 0; } console.timeEnd("FALSE test20") console.log("----------------------------") console.time("TRUE test21") i=0; for(;i<100000000;i=i+1){ true >>> 0; } console.timeEnd("TRUE test21") console.time("FALSE test22") i=0; for(;i<100000000;i=i+1){ false >>> 0; } console.timeEnd("FALSE test22") console.log("----------------------------") console.time("TRUE test23") i=0; for(;i<100000000;i=i+1){ true << 0; } console.timeEnd("TRUE test23") console.time("FALSE test24") i=0; for(;i<100000000;i=i+1){ false << 0; } console.timeEnd("FALSE test24") console.log("----------------------------") console.time("TRUE test25") i=0; for(;i<100000000;i=i+1){ ~~true; } console.timeEnd("TRUE test25") console.time("FALSE test26") i=0; for(;i<100000000;i=i+1){ ~~false; } console.timeEnd("FALSE test26") console.log("----------------------------") console.time("TRUE test25.1") i=0; for(;i<100000000;i=i+1){ ~true*-1-1; } console.timeEnd("TRUE test25.1") console.time("FALSE test26.1") i=0; for(;i<100000000;i=i+1){ ~false*-1-1; } console.timeEnd("FALSE test26.1") console.log("----------------------------") console.time("TRUE test27") i=0; for(;i<100000000;i=i+1){ true/1; } console.timeEnd("TRUE test27") console.time("FALSE test28") i=0; for(;i<100000000;i=i+1){ false/1; } console.timeEnd("FALSE test28")
结果
TRUE test1: 93.301ms FALSE test2: 102.854ms ---------------------------- TRUE test1.1: 118.979ms FALSE test2.1: 119.061ms ---------------------------- TRUE test3: 97.265ms FALSE test4: 108.389ms ---------------------------- TRUE test5: 85.854ms FALSE test6: 87.449ms ---------------------------- TRUE test7: 83.126ms FALSE test8: 84.992ms ---------------------------- TRUE test9: 99.683ms FALSE test10: 87.080ms ---------------------------- TRUE test9.1: 85.587ms FALSE test10.1: 86.050ms ---------------------------- TRUE test9.2: 85.883ms FALSE test10.2: 89.066ms ---------------------------- TRUE test9.3: 86.722ms FALSE test10.3: 85.187ms ---------------------------- TRUE test11: 86.245ms FALSE test12: 85.808ms ---------------------------- TRUE test13: 84.192ms FALSE test14: 84.173ms ---------------------------- TRUE test15: 81.575ms FALSE test16: 81.699ms ---------------------------- TRUE test17: 81.979ms FALSE test18: 81.599ms ---------------------------- TRUE test19: 81.578ms FALSE test20: 81.452ms ---------------------------- TRUE test21: 115.886ms FALSE test22: 88.935ms ---------------------------- TRUE test23: 82.077ms FALSE test24: 81.822ms ---------------------------- TRUE test25: 81.904ms FALSE test26: 82.371ms ---------------------------- TRUE test25.1: 82.319ms FALSE test26.1: 96.648ms ---------------------------- TRUE test27: 89.943ms FALSE test28: 83.646ms
试一试
val*1
let t=true; let f=false; console.log(t*1); console.log(f*1)
在我的上下文中,React Native,我从布尔获取不透明度值,最简单的方法:使用一元+运算符。
这将布尔值转换为数字;
style={ opacity: +!isFirstStep() }
+!!允许你在一个变量上应用它,即使它是undefined:
+!!
undefined
+!!undefined // 0 +!!false // 0 +!!true // 1 +!!(<boolean expression>) // 1 if it evaluates to true, 0 otherwise
Number
+bool
if
bool | 0
1 * bool
这是一个相当老的问题,有很多有效的答案。我注意到这里所有的基准测试都是不相关的——没有一个会考虑分支 预测。此外,现在JS引擎不只是简单地解释代码,他们JIT 编译本机机器码,并在执行之前优化它。这意味着,除了分支预测,编译器甚至可以用表达式的最终值替换表达式。
那么,这两个因素是如何影响布尔到整数转换的性能的呢?让我们一探究竟!在开始基准测试之前,了解基准测试的对象是很重要的。对于转换,我们使用以下7种转换方法:
Number(bool)
bool ? 1 : 0
bool & 1
~~bool
bool * 1
“Conversion"意味着将false转换为0,将true转换为11。每种转换方法运行100000次,测量操作/毫秒。在下表中,转换方法将根据其结果进行分组。结果后的百分比表示在同一浏览器中,该方法与最快方法相比有多慢。如果没有百分比,该方法要么是最快的,要么差异可以忽略不计(<0.01%)。测试运行在一台16英寸的Macbook Pro电脑上,配有Apple M1 Pro 10核CPU和16GB内存。浏览器有Chrome 102、Firefox 101和Safari 15.5。
第一个基准转换常量true:
现在的结果更加一致了。我们在不同浏览器中看到类似的三元if、位和乘法方法,并且Number构造函数在Firefox上的性能最差。三元在生成分支时落在后面。Safari似乎是我们整体表现最好的,每种方法都能产生极快的结果!
现在让我们看看分支预测如何通过下面的基准影响我们的结果,其中我们将布尔变量改为Math.random() < 0.01,这意味着1% true, 99% false。
Math.random() < 0.01
意想不到的?预期?我认为是后者,因为在这种情况下,分支预测在几乎所有情况下都是成功的,因为三元if和位hack之间的差异较小。其他的结果都是一样的,这里就不多说了。我仍然要指出Number在Firefox中的可怕性能——为什么?
这将我们带回到最初的问题:如何在Javascript中将bool类型转换为int类型?以下是我的建议:
if (bool)
-1 * (a < b) + 1 * (a > b)
还有一些细节:
我将永远感谢你一直读到最后——这是我第一个更长的、重要的StackOverflow回答,如果它有帮助和深刻的见解,对我来说意味着世界。如果你发现任何错误,请随时纠正我!
以前的基准测试工具提供了模糊的结果,没有测量单位。我对它进行了更改,并为Safari添加了基准测试,这对结论产生了影响。
将建议的方法放在jsben.ch中: https://jsben.ch/d33N1 . < / p >
每次测试都会给出不同的结果,但每次测试中最好的方法是位操作:0|bool / bool|0 / 1&bool / 1&bool / ~~bool。
0|bool
bool|0
1&bool
所有浏览器都支持,支持输入布尔值或布尔值的字符串表示形式
var yourVarAsStringOrBoolean; yourVarAsStringOrBoolean = "true"; //1 yourVarAsStringOrBoolean = "True"; //1 yourVarAsStringOrBoolean = "false"; //0 yourVarAsStringOrBoolean = false; //0 var resultAsInterger = Number(JSON.parse(yourVarAsStringOrBoolean.toString().toLowerCase()));
使用Chrome控制台检查它,它的工作
Number(JSON.parse(false.toString().toLowerCase())); Number(JSON.parse("TRUE".toString().toLowerCase()));
在JavaScript中,布尔到整数的转换可以通过以下方式完成:
在之前的回答中,其中一些已经被涵盖,但是,你可以发现一些缺失的内容如下:
// using arithmetic operators true + 0; // 1 false + 0; // 0 true - 0; // 1 false - 0; // 0 true * 1 // 1 false * 1 // 0 true / 1; // 1 false / 1; // 0
// using bitwise operators true & 1; // 1 false & 1; // 0 true | 0; // 1 false | 0; // 0 true ^ 0; // 1 false ^ 0; // 0
// using bitwise shift operators true >> 0; // 1 false >> 0; // 0 true >>> 0; // 1 false >>> 0; // 0 true << 0; // 1 false << 0; // 0
这些工作是因为JavaScript在执行这些操作时在内部将布尔值强制转换为整数等价物。
需要注意的一点是,当你不确定变量总是具有布尔值时,所有这些方法(除了使用三元运算符)都可能返回NaN。
NaN
为那些有兴趣了解更多的人写了博客。