У меня есть переменная, которая хранит false
или true
, но мне нужно 0
или 1
вместо, соответственно. Как я могу это сделать?
bool === true ? 1 : 0
, так как он на сегодняшний день самый быстрый в V8.
bool ? 1 : 0;
У меня есть переменная, которая хранит false
или true
, но мне нужно 0
или 1
вместо, соответственно. Как я могу это сделать?
bool === true ? 1 : 0
, так как он на сегодняшний день самый быстрый в V8.
bool ? 1 : 0;
Ответы:
Javascript имеет троичный оператор, который вы можете использовать:
var i = result ? 1 : 0;
NaN
. Так что, если вы хотите L33T и гарантируете ввод, переходите на другую, иначе лучше использовать троичный + правдивый тест.
Используйте унарный +
оператор , который преобразует свой операнд в число.
+ true; // 1
+ false; // 0
Обратите внимание, конечно, что вы все равно должны санировать данные на стороне сервера, потому что пользователь может отправлять любые данные вашему серверу, независимо от того, что говорит код на стороне клиента.
Number()
еще медленнее.
bool === true ? 1 : 0
это самый быстрый, с близкой секундой от bool | 0
.
Imho лучшее решение:
fooBar | 0
Это используется в asm.js для принудительного использования целочисленного типа.
1
целое число, если fooBar нет?
Я предпочитаю использовать функцию Number . Он берет объект и преобразует его в число.
Пример:
var myFalseBool = false;
var myTrueBool = true;
var myFalseInt = Number(myFalseBool);
console.log(myFalseInt === 0);
var myTrueInt = Number(myTrueBool);
console.log(myTrueInt === 1);
Вы можете проверить это в jsFiddle .
Я создал сравнение JSperf всех предложенных ответов.
TL; DR - лучший вариант для всех существующих браузеров:
val | 0;
,
Обновить:
Кажется, что в наши дни все они довольно идентичны, за исключением того, что Number()
функция самая медленная, а самая лучшая val === true ? 1 : 0;
.
Типизированный способ сделать это будет:
Number(true) // 1
Number(false) // 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
Дальнейшее чтение Преобразования типов Глава 3.8 Полное руководство по Javascript.
Унарный +
оператор позаботится об этом:
var test = true;
// +test === 1
test = false;
// +test === 0
Вы, естественно, захотите проверить это на сервере перед сохранением, так что в любом случае это может быть более разумным местом для этого.
===
, потому что true == 1
это правда, даже если вы "явное преобразование :-) true === 1
вместо этого ложно.
Я просто имел дело с этой проблемой в каком-то коде, который писал. Моим решением было использовать побитовое и.
var j = bool & 1;
Более быстрый способ справиться с постоянной проблемой - создать функцию. Это лучше читается другими людьми, лучше для понимания на этапе обслуживания и избавляет от возможности написать что-то не так.
function toInt( val ) {
return val & 1;
}
var j = toInt(bool);
Изменить - 10 сентября 2014 г.
По какой-то причине в Chrome не выполняется преобразование с использованием троичного оператора с идентичным оператору. Не имеет смысла, почему это быстрее, но я полагаю, что это своего рода оптимизация низкого уровня, которая имеет смысл где-то по пути.
var j = boolValue === true ? 1 : 0;
Проверьте сами: http://jsperf.com/boolean-int-conversion/2
В FireFox и Internet Explorer использование версии, которую я разместил, обычно происходит быстрее.
Редактировать - 14 июля 2017
Хорошо, я не собираюсь говорить вам, какой из них вы должны или не должны использовать. Каждый взбешенный браузер постоянно поднимал и опускался в зависимости от того, насколько быстро они могут выполнять операции с каждым методом. В какой-то момент у Chrome битовая версия работала лучше, чем у других, но вдруг все стало намного хуже. Я не знаю, что они делают, поэтому я просто оставлю это тем, кого это волнует. Редко есть причина беспокоиться о том, как быстро выполняется такая операция. Даже на мобильном телефоне это пустая операция.
Кроме того, вот новый метод для добавления прототипа toInt, который нельзя перезаписать.
Object.defineProperty(Boolean.prototype, "toInt", { value: function()
{
return this & 1;
}});
В моем контексте, React Native, где я получаю значение непрозрачности из логического, самый простой способ: использовать унарный оператор +.
+ true; // 1
+ false; // 0
Это преобразует логическое число в число;
style={ opacity: +!isFirstStep() }
Вы можете сделать это, просто расширив логический прототип
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 в качестве своего выхода.
Я протестировал все эти примеры, сделал тест и, наконец, рекомендую выбрать более короткий, он не влияет на производительность.
Работает на сервере 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
если вы хотите, чтобы целочисленное значение x изменялось с 1 на 0, а с 0 на 1 вы можете использовать (x + 1)% 2