Так много ответов делают половину работы. Да, !!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
коллекции.
РЕДАКТИРОВАТЬ 24 октября 2017 г., 6 февраля 19:
Сторонние библиотеки, которые ожидают явные логические значения
Вот интересный случай ... !!
может быть полезным, когда сторонние библиотеки ожидают явных логических значений.
Например, False в JSX (React) имеет особое значение, которое не вызывается простой ложью. Если вы попытались вернуть что-то вроде следующего в ваш JSX, ожидая int в messageCount
...
{messageCount && <div>You have messages!</div>}
... вы можете быть удивлены, увидев, что React рендерит, 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; это должен быть строго типизированный логический тип. Это означает, что если myObject
он строго типизирован , return !myObject;
работает для функции, возвращающей логическое значение, но return myObject;
не работает. Вы должны return !!myObject
соответствовать ожиданиям Typescript.
Исключение для Typescript? Если myObject
был any
, вы вернулись в JavaScript Дикого Запада и может вернуть его без !!
, даже если ваш тип возвращаемого значения является логическим.
Имейте в виду, что это соглашения JSX и Typescript , а не присущие JavaScript .
Но если вы видите странные 0
s в вашем рендеринге JSX, подумайте о ложном управлении.