Так много ответов делают половину работы. Да, !!X
можно прочитать как «истинность X [представлена как логическое значение]». Но !!
, на самом деле, не так важен для выяснения, является ли единственная переменная (или даже если много переменных) истинной или ложной. !!myVar === true
- это то же самое, что и myVar
. Сравнение !!X
с «настоящим» логическим значением не очень полезно.
То, что вы получаете с !!
, - это возможность проверять достоверность нескольких переменных друг против друга повторяемым, стандартизированным (и дружественным к JSLint) способом.
Просто кастинг: (
То есть ...
0 === false
- это false
.
!!0 === false
- это true
.
Выше не очень полезно. if (!0)
дает те же результаты, что и if (!!0 === false)
. Я не могу придумать хорошего случая для приведения переменной к логическому значению, а затем сравнения с «истинным» логическим значением.
См. "== and! =" Из Указания JSLint (примечание: Крокфорд немного перемещает свой сайт; в какой-то момент эта ссылка может умереть), чтобы узнать, почему:
Операторы == и! = Выполняют приведение типов перед сравнением. Это плохо, потому что это заставляет '\ t \ r \ n' == 0 быть верным. Это может маскировать ошибки типа. JSLint не может надежно определить, правильно ли используется ==, поэтому лучше вообще не использовать == и! = И всегда вместо этого использовать более надежные операторы === и! ==.
Если вас волнует только то, что значение является правдивым или ложным, используйте короткую форму. Вместо
(foo != 0)
просто скажи
(foo)
и вместо
(foo == 0)
1050 * говорят *
(!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
и это правда! Та же самая правдивость! (В этом случае оба «имеют ложную правду».)
Таким образом, единственное место, где вам действительно нужно было бы использовать «переменные логического преобразования», было бы, если бы у вас была ситуация, когда вы проверяли, имеют ли обе переменные одинаковую истинность, верно? То есть, используйте !!
, если вам нужно увидеть, являются ли две переменные правдивыми или ложными (или нет), то есть равно (или нет) truthiness .
Я не могу придумать отличный, не надуманный сценарий использования для этого случая. Может быть, у вас есть «связанные» поля в форме?
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>}
(или чего-то менее надуманного).
Одно исправление включает в себя взрыв, который приводит 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, подумайте о свободном управлении ложным.