我有一个存储false或true的变量,但我需要分别为0或1。我该怎么做呢?
当前回答
let integerVariable = booleanVariable * 1;
其他回答
let integerVariable = booleanVariable * 1;
TL;DR:避免数字构造函数和+bool;默认情况下使用简单的if;如果项目中的基准测试这样做更好,请使用bool | 0,1 * bool。
这是一个相当老的问题,有很多有效的答案。我注意到这里所有的基准测试都是不相关的——没有一个考虑到分支预测。而且,现在JS引擎不只是简单地解释代码,而是将其JIT编译为本机机器码,并在执行之前对其进行优化。这意味着,除了分支预测,编译器甚至可以用表达式的最终值替换表达式。
那么,这两个因素是如何影响布尔到整数转换的性能的呢?让我们一探究竟!在开始基准测试之前,了解基准测试的对象是很重要的。对于转换,我们使用以下7种转换方法:
数字构造函数:Number(bool) If语句(使用三元):bool ?1:0 一元运算符+:+bool 按位OR: bool | 0 按位AND: bool & 1 位双NOT: ~~bool 数字乘法:bool * 1
"Conversion" means converting false to 0 and true to 11. Each conversion method is ran 100000 times, measuring operations/millisecond. In the following tables, conversion methods will be grouped to their results accordingly. The percentage after the result represents how slow this method is compared to the fastest, in the same browser. If there is no percentage, the method is either the fastest or the difference is negligible (<0.01%). Benchmarks are run on a Macbook Pro 16-inch machine, with the Apple M1 Pro 10-core CPU and 16GB of RAM. Browsers are Chrome 102, Firefox 101 and Safari 15.5.
第一个基准测试转换常量true:
Method | Chrome (V8) | Firefox (Spidermonkey) | Safari (Webkit) |
---|---|---|---|
Number(bool) |
31745.89 | 392.35 - 91.48% | 31231.79 |
bool ? 1 : 0 |
31592.8 - 0.48% | 4602.64 | 27533.47 - 11.84% |
+bool |
31332.57 - 1.3% | 4463.41 - 3.02% | 27378.7 - 12.34% |
bool | 0 |
31488.5 - 0.81% | 4441.4 - 3.5% | 27222 - 12.84% |
bool & 1 |
31383.17 - 1.14% | 4459.64 - 3.11% | 27317.41 - 12.53% |
~~bool |
31265.85 - 1.51% | 4442.35 - 3.48% | 27434.72 - 12.16% |
bool * 1 |
31374.4 - 1.17% | 4444.05 - 3.45% | 27381.19 - 12.33% |
Interesting! V8 shows some huge numbers, all of them approximately the same! Spidermonkey doesn't really shine, but we can see that the bitwise and multiplication tricks come first, and the ternary if second. Finally, Webkit's Number does similarly to V8's and the other methods fall behind, but are all close to each other. What are the takeaways? Browsers mostly manage to replace our conversions with simply the value 1. This optimization will take place where we can mentally replace the boolean to a constant value. The Number constructor is an intriguing anomaly - it severly falls behind in Firefox (91% slower!), while in Safari it is the fastest!
上述情况在实际项目中是不会遇到的。所以让我们改变变量:bool值现在是Math.random() < 0.5。这就产生了50%的真概率,50%的假概率。我们的结果会改变吗?让我们运行这个基准测试来看看。
Method | Chrome (V8) | Firefox (Spidermonkey) | Safari (Webkit) |
---|---|---|---|
Number(bool) |
1648.83 - 2.26% | 280.34 - 86.4% | 8014.69 |
bool ? 1 : 0 |
804.27 - 52.32% | 731.57 - 64.5% | 1294.02 - 83.85% |
+bool |
1670.79 - 0.95% | 2057.94 | 7753.99 - 3.25% |
bool | 0 |
1668.22 - 1.11% | 2054.17 | 7764.81 - 3.12% |
bool & 1 |
1675.52 - 0.67% | 2056.76 | 7193.08 - 10.25% |
~~bool |
1676.24 - 0.63% | 2056.18 | 7669.48 - 4.31% |
bool * 1 |
1686.88 | 2060.88 | 7751.48 - 3.28% |
现在的结果更加一致了。我们可以在不同浏览器中看到类似的三元if、位和乘法方法,并且Number构造函数在Firefox上的性能最差。三元在生成分支时落在后面。Safari似乎是我们整体表现最好的,每种方法都能产生极快的结果!
现在让我们看看分支预测如何影响下面基准测试的结果,其中我们将布尔变量改为Math.random() < 0.01,这意味着1%为真,99%为假。
Method | Chrome (V8) | Firefox (Spidermonkey) | Safari (Webkit) |
---|---|---|---|
Number(bool) |
1643.13 - 1.68% | 280.06 - 86.4% | 8071.65 |
bool ? 1 : 0 |
1590.55 - 4.83% | 1970.66 - 4.32% | 7119.59 - 11.8% |
+bool |
1662.09 - 0.55% | 2054.09 | 7762.03 - 3.84% |
bool | 0 |
1669.35 | 2051.85 | 7743.95 - 4.06% |
bool & 1 |
1661.09 - 0.61% | 2057.62 | 7454.45 - 7.65% |
~~bool |
1662.94 - 0.5% | 2059.65 | 7739.4 - 4.12% |
bool * 1 |
1671.28 | 2048.21 | 7787.38 - 3.52% |
意想不到的?预期?我认为是后者,因为在这种情况下,分支预测在几乎所有情况下都是成功的,因为三元if和位hack之间的差异较小。其他的结果都是一样的,这里就不多说了。我还是要指出数字在Firefox中的糟糕表现——为什么?
这将我们带回到最初的问题:如何在Javascript中将bool类型转换为int类型?以下是我的建议:
Use if statements, in general. Don't get smart - the browser will do better, usually, and usually means most of the situations. They are the most readable and clear out of all the methods here. While we're at readability, maybe use if (bool) instead of that ugly ternary! I wish Javascript had what Rust or Python have... Use the rest when it's truly necessary. Maybe benchmarks in your project perform sub-standard, and you found that a nasty if causes bad performance - if that's the case, feel free to get into branchless programming! But don't go too deep in that rabbit hole, nobody will benefit from things like -1 * (a < b) + 1 * (a > b), believe me.
还有一些细节:
Avoid Number(bool). While it is true that the Chromium platform (Chrome + Edge) has about 68% market share globally, Safari 19% and Firefox a mere 3.6%, there are enough other fast-performing methods that won't fully sacrifice a percentage of your users. Firefox has 7% desktop market share, which amounts to a sizable number of 173 million users. In older benchmarks, +bool performed similarly bad to Number in Firefox, maybe take this in consideration, too - bitwise hacks and multiplication give consistently performant results across all browsers, in all situations. bool | 0 has the best chance to be familiar to other developers.
我将永远感谢你一直读到最后——这是我第一个更长的、重要的StackOverflow回答,如果它有帮助和深刻的见解,对我来说意味着世界。如果你发现任何错误,请随时纠正我!
编辑:之前的基准测试工具提供了模糊的结果,没有一个度量单位。我对它进行了更改,并为Safari添加了基准测试,这对结论产生了影响。
定义了转换,因为它并不真正清楚布尔到整数的含义。例如,Go根本不支持这种转换。
在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。
为那些有兴趣了解更多的人写了一篇博客。
所有浏览器都支持,支持输入布尔值或布尔值的字符串表示形式
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()));
使用一元+运算符,将其操作数转换为数字。
+ true; // 1
+ false; // 0
当然,请注意,您仍然应该在服务器端清除数据,因为用户可以将任何数据发送到您的服务器,而不管客户端代码说了什么。
推荐文章
- 如何在Typescript中解析JSON字符串
- Javascript reduce()在对象
- 在angularJS中& vs @和=的区别是什么
- 错误"Uncaught SyntaxError:意外的标记与JSON.parse"
- JavaScript中的querySelector和querySelectorAll vs getElementsByClassName和getElementById
- 给一个数字加上st, nd, rd和th(序数)后缀
- 如何以编程方式触发引导模式?
- setTimeout带引号和不带括号的区别
- 在JS的Chrome CPU配置文件中,'self'和'total'之间的差异
- 用javascript检查输入字符串中是否包含数字
- 如何使用JavaScript分割逗号分隔字符串?
- 在Javascript中~~(“双波浪号”)做什么?
- 谷歌chrome扩展::console.log()从后台页面?
- 未捕获的SyntaxError:
- [].slice的解释。调用javascript?