hd.*_*hd. 243 javascript integer boolean numbers type-conversion
我有一个变量存储false
或true
,但我需要0
或1
相反.我怎样才能做到这一点?
lon*_*day 412
使用一元运算+
符,将其操作数转换为数字.
+ true; // 1
+ false; // 0
Run Code Online (Sandbox Code Playgroud)
当然,请注意,您仍应该清理服务器端的数据,因为无论客户端代码说什么,用户都可以向服务器发送任何数据.
And*_*ose 312
Javascript有一个你可以使用的三元运算符:
var i = result ? 1 : 0;
Run Code Online (Sandbox Code Playgroud)
kra*_*lyk 104
Imho最好的解决方案是:
fooBar | 0
Run Code Online (Sandbox Code Playgroud)
这在asm.js中用于强制整数类型.
Ren*_*ené 49
我更喜欢使用Number函数.它需要一个对象并将其转换为数字.
例:
var myFalseBool = false;
var myTrueBool = true;
var myFalseInt = Number(myFalseBool);
console.log(myFalseInt == 0);
var myTrueInt = Number(myTrueBool);
console.log(myTrueInt == 1);
Run Code Online (Sandbox Code Playgroud)
或者在jsFiddle中运行它.
Gal*_*mor 39
我创建了所有建议答案的JSperf比较.
TL; DR - 所有当前浏览器的最佳选择是:
val | 0;
Run Code Online (Sandbox Code Playgroud)
.
更新:
看起来这些日子他们都非常相同,除了Number()
功能最慢,而最好的功能val === true ? 1 : 0;
.
Phi*_*nci 33
执行此操作的键入方式是:
Number(true) // 1
Number(false) // 0
Run Code Online (Sandbox Code Playgroud)
ton*_*amp 29
我今天刚遇到这条捷径.
~~(真)
~~(假)
人们比我能解释的要聪明得多:
http://james.padolsey.com/javascript/double-bitwise-not/
小智 16
当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
Run Code Online (Sandbox Code Playgroud)
进一步阅读类型转换Javascript权威指南的第3.8章.
Nic*_*ant 13
我只是在编写的一些代码中处理这个问题.我的解决方案是使用按位和.
var j = bool & 1;
Run Code Online (Sandbox Code Playgroud)
处理常量问题的更快方法是创建一个函数.它更容易被其他人阅读,更好地在维护阶段理解,并摆脱写错的可能性.
function toInt( val ) {
return val & 1;
}
var j = toInt(bool);
Run Code Online (Sandbox Code Playgroud)
编辑 - 2014年9月10日
由于某些原因,在Chrome中使用与运算符相同的三元运算符进行转换的速度更快.对于为什么它更快没有任何意义,但我认为它是某种低级优化,在某个地方有意义.
var j = boolValue === true ? 1 : 0;
Run Code Online (Sandbox Code Playgroud)
自己测试: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;
}});
Run Code Online (Sandbox Code Playgroud)
Gus*_*ors 11
一元运算+
符将负责这个:
var test = true;
// +test === 1
test = false;
// +test === 0
Run Code Online (Sandbox Code Playgroud)
在存储它之前,您自然希望在服务器上进行完整性检查,因此无论如何这可能是一个更明智的地方.
小智 9
您还可以添加0,使用shift运算符或xor:
val + 0;
val ^ 0;
val >> 0;
val >>> 0;
val << 0;
Run Code Online (Sandbox Code Playgroud)
它们的速度与其他答案的速度相似.
小智 9
在我的上下文中,我从布尔值获取不透明度值的 React Native,最简单的方法是:使用一元 + 运算符。
+ true; // 1
+ false; // 0
Run Code Online (Sandbox Code Playgroud)
这将布尔值转换为数字;
style={ opacity: +!isFirstStep() }
Run Code Online (Sandbox Code Playgroud)
Number
构造函数,一元+
;一直使用简单if
的;求助于bool | 0
或1 * bool
如果您的项目中的基准以这种方式做得更好。这是一个相当古老的问题,有很多有效的答案。我注意到的一点是,这里的所有基准都是无关紧要的——没有一个考虑分支 预测。此外,如今,JS 引擎不再简单地解释代码,而是将其JIT 编译为本地机器代码并在执行之前对其进行优化。这意味着,除了分支预测之外,编译器甚至可以用它们的最终值替换表达式。
现在,这两个因素如何影响布尔到整数转换的性能?让我们一探究竟吧!在我们进入基准测试之前,了解我们的基准测试很重要。对于转换,我们使用以下七种转换方法:
Number(bool)
bool ? 1 : 0
+
:+bool
bool | 0
bool & 1
~~bool
bool * 1
“转换”是指转换false
为0
和true
为1
1。每种转换方法运行 100000 次,测量操作数/毫秒。在下表中,转换方法将根据其结果进行分组。结果来自我的机器,它的 CPU 为 AMD Ryzen 7 4800HS。
第一个基准转换常数true
:
方法 | 边缘/铬 (V8) | 火狐(蜘蛛猴) |
---|---|---|
Number(bool) |
83103 | 1088 |
bool ? 1 : 0 |
83073 | 7732 |
+bool |
83372 | 1043 |
bool | 0 |
83479 | 9344 |
bool & 1 |
83242 | 9354 |
~~bool |
83293 | 9316 |
bool * 1 |
83504 | 9316 |
有趣的!V8 显示了一些巨大的数字,它们都大致相同!Spidermonkey 并没有真正发光,但我们可以看到按位和乘法技巧排在第一位,然后是三元。什么是外卖?Chrome 浏览器设法用简单的价值取代了我们的转化1
。这种优化将发生在我们可以将布尔值替换为常量值的地方。
以上不是我们在实际项目中会遇到的情况。所以让我们改变我们的变量: bool 现在是Math.random() < 0.5
。这产生 50% 的机会true
,50% 的false
。我们的结果会改变吗?让我们运行这个基准测试看看。
方法 | 边缘/铬 (V8) | 火狐(蜘蛛猴) |
---|---|---|
Number(bool) |
2405 | 662 |
bool ? 1 : 0 |
1482 | 1580 |
+bool |
2386 | 673 |
bool | 0 |
2391 | 2499 |
bool & 1 |
2409 | 2513 |
~~bool |
2341 | 2493 |
bool * 1 |
2398 | 2518 |
现在的结果更加一致。我们看到三元 if、bitwise 和乘法方法的数字相似,但Number
构造函数和一元+
在 V8 上表现更好。我们可以从数字推测 V8 用它用于按位技巧的任何指令替换它们,但在 Spidermonkey 中,这些函数完成了所有工作。
我们还没有解决我们上面提到的一个因素:分支预测。在这个基准测试中,让我们将布尔变量更改为Math.random() < 0.01
,这意味着 1% true
、 99% false
。
方法 | 边缘/铬 (V8) | 火狐(蜘蛛猴) |
---|---|---|
Number(bool) |
2364 | 865 |
bool ? 1 : 0 |
2352 | 2390 |
+bool |
2447 | 777 |
bool | 0 |
2421 | 2513 |
bool & 1 |
2400 | 2509 |
~~bool |
2446 | 2501 |
bool * 1 |
2421 | 2497 |
意外?预期的?我会说后者,因为在这种情况下,分支预测几乎在所有情况下都是成功的,考虑到三元 if 和按位黑客之间的微小差异。所有其他结果都是一样的,这里就不多说了。
这一努力让我们回到了最初的问题:如何在 Javascript 中将 bool 转换为 int?以下是我的建议:
Number(bool)
和+bool
。这 2 种方法在幕后做了很多工作,尽管 Chrome 设法在我们的基准测试中优化了它们,但 Firefox 没有,并且可能在某些情况下编译器不会完成这些优化。除此之外,并不是每个人都在使用 Chrome!我还得忍受,不是吗?...if (bool)
而不是那个丑陋的三元!我希望 Javascript 拥有Rust或Python 所拥有的......if
导致性能不佳 - 如果是这种情况,请随时进入无分支 编程!但是不要在那个兔子洞里钻得太深-1 * (a < b) + 1 * (a > b)
,相信我,没有人会从诸如此类的事情中受益。我将永远感谢您阅读到最后——这是我第一个更长、更重要的 StackOverflow 答案,如果它对我有帮助和洞察力,它对我来说意味着整个世界。如果您发现任何错误,请随时纠正我!
+!!
允许您将其应用于变量,即使它是undefined
:
+!!undefined // 0
+!!false // 0
+!!true // 1
+!!(<boolean expression>) // 1 if it evaluates to true, 0 otherwise
Run Code Online (Sandbox Code Playgroud)
JavaScript 中布尔到整数的转换可以通过以下方式完成:
Number()
在之前的答案中已经涵盖了其中一些内容,但是,您可以找到一些缺失的内容,如下所示:
// 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
Run Code Online (Sandbox Code Playgroud)
// using bitwise operators
true & 1; // 1
false & 1; // 0
true | 0; // 1
false | 0; // 0
true ^ 0; // 1
false ^ 0; // 0
Run Code Online (Sandbox Code Playgroud)
// using bitwise shift operators
true >> 0; // 1
false >> 0; // 0
true >>> 0; // 1
false >>> 0; // 0
true << 0; // 1
false << 0; // 0
Run Code Online (Sandbox Code Playgroud)
这些之所以有效,是因为 JavaScript 在执行这些操作时会在内部将布尔值强制转换为其等效的整数。
NaN
需要注意的重要一点是,当您不确定变量始终具有布尔值时,所有这些方法([使用三元运算符][2]除外)都可能返回。
为有兴趣了解更多信息的人写了一篇博客文章。
归档时间: |
|
查看次数: |
174260 次 |
最近记录: |