Tak wiele odpowiedzi robi połowę pracy. Tak, !!Xmoż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 === truejest taki sam jak sprawiedliwy myVar. Porównywanie !!Xdo „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 === falsejest false.
!!0 === falsejest 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ę ( truejest rzutowana na 1i falsena 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 === myVar2jest 0 === undefinedi jest oczywiście fałszywe.
!!myVar1 === !!myVar2jest !!0 === !!undefinedi 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 errorObjectskolekcji.
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, 0gdy 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 0się !!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 myObjectjest silnie wpisany , return !myObject;działa dla funkcji zwracającej wartość logiczną, ale return myObject;nie działa. Musisz return !!myObjectdopasować się do oczekiwań maszynopisu.
Wyjątek dla maszynopisu? Jeśli myObjecttak 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 0znaki w renderowanym JSX, pomyśl luźne zarządzanie fałszem.