Tak wiele odpowiedzi robi połowę pracy. Tak, !!X
można to odczytać jako „prawdziwość X [przedstawionej jako logiczna]”. Ale !!
praktycznie nie jest tak ważne, aby dowiedzieć się, czy pojedyncza zmienna jest (a nawet jeśli wiele zmiennych jest) prawdą czy fałszem. !!myVar === true
jest taki sam jak sprawiedliwy myVar
. Porównywanie !!X
do „prawdziwych” wartości logicznych nie jest tak naprawdę przydatne.
Co można zyskać ze !!
jest możliwość sprawdzenia truthiness wielu zmiennych przeciwko siebie w powtarzalny, standaryzowane (a) JSLint przyjazny sposób.
Po prostu casting :(
To jest...
0 === false
jest false
.
!!0 === false
jest true
.
Powyższe nie jest tak przydatne. if (!0)
daje takie same wyniki jak if (!!0 === false)
. Nie mogę wymyślić dobrego argumentu za rzutowaniem zmiennej na wartość logiczną, a następnie na porównanie z „prawdziwą” wartością logiczną.
Zobacz „== i! =” Ze wskazówek JSLinta (uwaga: Crockford trochę przesuwa swoją stronę; ten link może umrzeć w pewnym momencie), aby dowiedzieć się, dlaczego:
Operatory == i! = Dokonują przymusu typu przed porównaniem. Jest to złe, ponieważ powoduje, że '\ t \ r \ n' == 0 jest prawdą. Może to maskować błędy typu. JSLint nie może wiarygodnie ustalić, czy == jest używane poprawnie, dlatego najlepiej nie używać w ogóle == i! = I zawsze używać bardziej niezawodnych operatorów === i! ==.
Jeśli zależy ci tylko na tym, że wartość jest prawdą lub fałszem, skorzystaj z krótkiej formy. Zamiast
(foo != 0)
tylko powiedz
(foo)
i zamiast
(foo == 0)
mówić
(!foo)
Należy zauważyć, że istnieją nieintuicyjne przypadki, w których wartość logiczna zostanie rzutowana na liczbę ( true
jest rzutowana na 1
i false
na 0
) podczas porównywania wartości logicznej z liczbą. W takim przypadku !!
może być przydatny psychicznie. Chociaż znowu są to przypadki, w których porównujesz nie-boolean z booleanem o twardym typie, co jest, imo, poważnym błędem. if (-1)
jest wciąż do zrobienia tutaj.
╔═══════════════════════════════════════╦═══════════════════╦═══════════╗
║ 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
╚═══════════════════════════════════════╩═══════════════════╩═══════════╝
A wszystko staje się jeszcze bardziej szalone w zależności od silnika. Na przykład WScript wygrywa nagrodę.
function test()
{
return (1 === 1);
}
WScript.echo(test());
Z powodu jakiegoś historycznego jive Windowsa , to wyświetli -1 w oknie komunikatu! Wypróbuj w wierszu polecenia cmd.exe i przekonaj się! Ale WScript.echo(-1 == test())
wciąż daje ci 0 lub WScript false
. Odwracać wzrok. To ohydne.
Porównywanie prawdy :)
Ale co, jeśli mam dwie wartości, muszę sprawdzić równość truthi / falsi-nizm?
Udawaj, że mamy myVar1 = 0;
i myVar2 = undefined;
.
myVar1 === myVar2
jest 0 === undefined
i jest oczywiście fałszywe.
!!myVar1 === !!myVar2
jest !!0 === !!undefined
i jest prawdą! Ta sama prawda! (W tym przypadku oba „mają prawdziwość fałszu”).
Tak więc jedynym miejscem, w którym naprawdę potrzebowałbyś użyć „zmiennych obsadzonych logicznie” byłoby, gdybyś miał sytuację, w której sprawdzasz, czy obie zmienne mają tę samą prawdziwość, prawda? To znaczy, użyj, !!
jeśli chcesz zobaczyć, czy dwie zmienne są prawdomówne, czy obie fałszywe (lub nie), to znaczy o równej (lub nie) prawdomówności .
Nie mogę wymyślić świetnego, nieskomplikowanego przypadku użycia dla tego odręcznego. Może masz „połączone” pola w formularzu?
if (!!customerInput.spouseName !== !!customerInput.spouseAge ) {
errorObjects.spouse = "Please either enter a valid name AND age "
+ "for your spouse or leave all spouse fields blank.";
}
Więc teraz, jeśli masz prawdę dla obu lub fałsz zarówno dla nazwiska małżonka, jak i wieku, możesz kontynuować. W przeciwnym razie masz tylko jedno pole z wartością (lub bardzo wczesne małżeństwo) i musisz stworzyć dodatkowy błąd w swojej errorObjects
kolekcji.
EDYCJA 24 października 2017 r., 6 lutego 19:
Biblioteki stron trzecich, które oczekują wyraźnych wartości logicznych
Oto interesujący przypadek ... !!
może być przydatny, gdy biblioteki innych firm oczekują wyraźnych wartości logicznych.
Na przykład Fałsz w JSX (React) ma specjalne znaczenie, które nie jest wywoływane w przypadku zwykłego fałszu. Jeśli próbowałeś zwrócić coś takiego w JSX, oczekując int w messageCount
...
{messageCount && <div>You have messages!</div>}
... możesz być zaskoczony, gdy React renderuje, 0
gdy masz zero wiadomości. Musisz jawnie zwrócić wartość false, aby JSX nie renderował. Powyższa instrukcja zwraca 0
, którą JSX chętnie renderuje, tak jak powinien. Nie może powiedzieć, że nie miałeś Count: {messageCount && <div>Get your count to zero!</div>}
(lub czegoś mniej wymyślonego).
Jedna poprawka wymaga bangbang, przekształcająca 0
się !!0
, co jest false
:
{!!messageCount && <div>You have messages!</div>}
Dokumenty JSX sugerują, abyś był bardziej jednoznaczny, napisał kod do komentowania i użył porównania, aby wymusić wartość logiczną.
{messageCount > 0 && <div>You have messages!</div>}
Bardziej komfortowo radzę sobie z fałszowaniem za pomocą trójki -
{messageCount ? <div>You have messages!</div> : false}
Ta sama sprawa w Typescript: Jeśli masz funkcję, która zwraca wartość logiczną (lub przypisujesz wartość zmiennej boolean), zwykle nie możesz zwrócić / przypisać wartości boolean-y; musi to być silnie typ logiczny. Oznacza to, że iff myObject
jest silnie wpisany , return !myObject;
działa dla funkcji zwracającej wartość logiczną, ale return myObject;
nie działa. Musisz return !!myObject
dopasować się do oczekiwań maszynopisu.
Wyjątek dla maszynopisu? Jeśli myObject
tak any
, to wracasz do Dzikiego Zachodu JavaScript i możesz go zwrócić bez niego !!
, nawet jeśli typ zwrotu to wartość logiczna.
Pamiętaj, że są to konwencje JSX i maszynopisu , a nie te związane z JavaScript .
Ale jeśli widzisz dziwne 0
znaki w renderowanym JSX, pomyśl luźne zarządzanie fałszem.