Стільки відповідей виконують половину роботи. Так, !!X
можна прочитати як "правдивість X [представлена як булева]". Але !!
це практично не так важливо для з'ясування того, чи є одна змінна (або навіть якщо багато змінних) правдою чи хибністю. !!myVar === true
те саме, що просто myVar
. Порівнювати !!X
з "справжнім" булевим не дуже корисно.
Те, що ви отримуєте, !!
- це можливість перевірити правдивість декількох змінних один проти одного повторюваним, стандартизованим (і JSLint дружнім) способом.
Просто кастинг :(
Це є...
0 === false
є false
.
!!0 === false
є true
.
Сказане не так корисно. if (!0)
дає ті ж результати, що і if (!!0 === false)
. Я не можу придумати гарний випадок для того, щоб передати змінну на булеву, а потім порівняти з "справжньою" булевою.
Дивіться "== і! =" З вказівок JSLint (зверніть увагу: Крокфорд трохи пересуває свій сайт; це посилання може померти в якийсь момент) для трохи про те, чому:
Оператори == і! = Вводять примус перед порівнянням. Це погано, оскільки це призводить до того, що '\ t \ r \ n' == 0 відповідає дійсності. Це може замаскувати помилки типу. JSLint не може достовірно визначити, чи використовується == правильно, тому краще взагалі не використовувати == і! = Та завжди використовувати більш надійні оператори === та! ==.
Якщо ви хвилюєтесь лише тим, що цінність є фальшивою чи хибною, тоді використовуйте коротку форму. Замість
(foo != 0)
просто сказати
(foo)
і замість
(foo == 0)
сказати
(!foo)
Зауважте, що є деякі неінтуїтивні випадки, коли булеве значення буде приведено до числа ( true
передане до 1
та false
до 0
) при порівнянні булевого числа з числом. У цьому випадку !!
може бути корисною для психіки. Хоча, знову ж таки, це випадки, коли ви порівнюєте небулевий з жорстким типовим булевим, що є, імо, серйозною помилкою. if (-1)
- це все-таки шлях сюди.
╔═══════════════════════════════════════╦═══════════════════╦═══════════╗
║ Original ║ Equivalent ║ Result ║
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (-1 == true) console.log("spam") ║ if (-1 == 1) ║ undefined ║
║ if (-1 == false) console.log("spam") ║ if (-1 == 0) ║ undefined ║
║ Order doesn't matter... ║ ║ ║
║ if (true == -1) console.log("spam") ║ if (1 == -1) ║ undefined ║
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (!!-1 == true) console.log("spam") ║ if (true == true) ║ spam ║ better
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (-1) console.log("spam") ║ if (truthy) ║ spam ║ still best
╚═══════════════════════════════════════╩═══════════════════╩═══════════╝
А речі стають ще божевільнішими, залежно від вашого двигуна. Наприклад, WScript виграє приз.
function test()
{
return (1 === 1);
}
WScript.echo(test());
Через деякий історичний джив Windows, він виведе -1 у вікні повідомлень! Спробуйте в підказці cmd.exe і подивіться! Але WScript.echo(-1 == test())
все одно дає 0, або WScript false
. Озирнись. Це огидно.
Порівнюючи правдивість :)
Але що робити, якщо у мене є два значення, які мені потрібно перевірити на рівність правди / фальсисності?
Прикидаємось, що маємо myVar1 = 0;
і myVar2 = undefined;
.
myVar1 === myVar2
є 0 === undefined
і очевидно помилковий.
!!myVar1 === !!myVar2
є !!0 === !!undefined
і є правдою! Така ж правдивість! (У цьому випадку обидва "мають хибну правду".)
Тож єдиним місцем, яке б вам справді потрібно було використовувати "булеві змінні", було б, якби у вас була ситуація, коли ви перевіряєте, чи мають обидві змінні однакові правдивості, правда? Тобто, скористайтеся, !!
якщо вам потрібно, щоб переконатися, що дві версії є обома правдивими чи обома хибними (чи ні), тобто однаковою (чи ні) правдивістю .
Я не можу придумати чудовий, не надуманий випадок використання для цього назовні. Можливо, у вас є "пов’язані" поля у формі?
if (!!customerInput.spouseName !== !!customerInput.spouseAge ) {
errorObjects.spouse = "Please either enter a valid name AND age "
+ "for your spouse or leave all spouse fields blank.";
}
Отож, якщо у вас є підопічна для обох або фальшивість як для імені подружжя, так і для віку, ви можете продовжувати. Інакше у вас є лише одне поле зі значенням (або дуже ранній шлюб) і вам потрібно створити додаткову помилку у вашій errorObjects
колекції.
EDIT 24 жовтня 2017 р., 6 лютого 19 р.:
Бібліотеки сторонніх організацій, які очікують явних булевих значень
Ось цікавий випадок ... !!
може бути корисним, коли сторонні лібри очікують явних булевих значень.
Наприклад, False in JSX (React) має особливе значення, яке не викликається простою помилковістю. Якщо ви спробували повернути щось подібне у своєму JSX, очікуючи int in messageCount
...
{messageCount && <div>You have messages!</div>}
... ви можете бути здивовані, побачивши React render a, 0
коли у вас немає нульових повідомлень. Ви повинні явно повернути false, щоб JSX не відображав. Наведене вище твердження повертається 0
, яке JSX із задоволенням надає, як слід. Це не може сказати, що ви не мали Count: {messageCount && <div>Get your count to zero!</div>}
(або щось менш надумане).
Одним із способів виправити включає Bangbang, які примушують 0
в !!0
, що false
:
{!!messageCount && <div>You have messages!</div>}
Документи JSX пропонують вам бути більш чіткими, написати код самокоментування та використовувати порівняння для примушування до булевого.
{messageCount > 0 && <div>You have messages!</div>}
Мені зручніше поводитися з фальшивістю себе з потрійником -
{messageCount ? <div>You have messages!</div> : false}
Та сама угода в Typescript: Якщо у вас є функція, яка повертає булева (або ви призначаєте значення булевій змінній), ви [зазвичай] не можете повернути / призначити булеве значення y; він повинен бути сильно набраним булевим. Це означає, що iff myObject
сильно набраний , return !myObject;
працює для функції, що повертає булеву, але return myObject;
не робить. Ви повинні return !!myObject
відповідати очікуванням Typescript.
Виняток для Typescript? Якщо це myObject
було any
, ви знову на Дикому Заході JavaScript і можете повернути його без цього !!
, навіть якщо ваш тип повернення є булевим.
Майте на увазі, що це JSX & Typescript , а не властиві JavaScript .
Але якщо ви бачите дивні 0
s у своєму виведеному JSX, подумайте про некероване керування фальшивістю.