Co to jest? (Nie Nie) operator w JavaScript?

Widziałem jakiś kod, który używa operatora, którego nie rozpoznaję, w postaci dwóch wykrzykników, jak tak: !!. Czy ktoś może mi powiedzieć, czym zajmuje się ten operator?

Kontekst, w którym to zobaczyłem,

this.vertical = vertical !== undefined ? !!vertical : this.vertical;
Author: mc10, 2009-04-24

30 answers

Przymusza oObject do boolean. Gdyby było false (np. 0, null, undefined, itd.), będzie false, w przeciwnym razie true.

!oObject  //Inverted boolean
!!oObject //Non inverted boolean so true boolean representation

Więc !! nie jest operatorem, tylko ! operatorem dwa razy.

Przykład ze świata rzeczywistego "Test IE version":

let isIE8 = false;  
isIE8 = !! navigator.userAgent.match(/MSIE 8.0/);  
console.log(isIE8); // returns true or false 

If you ⇒

console.log(navigator.userAgent.match(/MSIE 8.0/));  
// returns null  

Ale jeśli]}

console.log(!!navigator.userAgent.match(/MSIE 8.0/));  
// returns true or false
 2173
Author: stevehipwell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-04 05:56:44

To strasznie niejasny sposób na konwersję typu.

! jest NIE . Tak więc !true jest false, A !false jest true. !0 jest true, a !1 jest false.

Więc konwertujesz wartość na wartość logiczną, a następnie odwracasz ją, a następnie odwracasz ponownie.

// Maximum Obscurity:
val.enabled = !!userId;

// Partial Obscurity:
val.enabled = (userId != 0) ? true : false;

// And finally, much easier to understand:
val.enabled = (userId != 0);
 747
Author: Tom Ritter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-26 14:08:52

!!expr Zwraca wartość logiczną (true lub false) w zależności od wartości prawdziwości wyrażenia. Ma to większy sens, gdy jest używane na typach nie-boolowskich. Rozważmy te przykłady, szczególnie trzeci przykład i dalej:

          !!false === false
           !!true === true

              !!0 === false
!!parseInt("foo") === false // NaN is falsy
              !!1 === true
             !!-1 === true  // -1 is truthy

             !!"" === false // empty string is falsy
          !!"foo" === true  // non-empty string is truthy
        !!"false" === true  // ...even if it contains a falsy value

     !!window.foo === false // undefined is falsy
           !!null === false // null is falsy

             !!{} === true  // an (empty) object is truthy
             !![] === true  // an (empty) array is truthy; PHP programmers beware!
 388
Author: Salman A,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-24 21:00:47

Zaparz trochę herbaty:

!! nie jest operatorem. Jest to podwójne użycie ! -- które jest operatorem logicznym "nie".


Teoretycznie:

! określa "prawdę" o tym, czym nie jest wartość:

  • Prawda jest taka, że false nie jest true (dlatego !false wyniki w true)

  • Prawda jest taka, że true nie jest false (dlatego !true wyniki w false)


!! określa "prawdę" jaka jest wartość Nie Nie:

  • Prawda jest taka, że true nie jest Nie true (dlatego !!true wyniki w true)

  • Prawda jest taka, że false nie jest Nie false (dlatego !!false wyniki w false)


To, co chcemy ustalić w porównaniu, To "prawda" o o wartość odniesienia, a nie wartość samego odniesienia. Istnieje przypadek użycia, w którym możemy chcieć poznać prawdę o wartości, nawet jeśli oczekujemy, że wartość będzie false (lub FALSE), lub jeśli oczekujemy, że wartość nie będzie typeof boolean.


W praktyce:

Rozważmy zwięzłą funkcję, która wykrywa funkcjonalność funkcji (a w tym przypadku Kompatybilność platformy) poprzez typowanie dynamiczne (aka " kaczka typowania"). Chcemy napisać funkcję, która zwraca true jeśli przeglądarka użytkownika obsługuje element HTML5 <audio>, ale nie chcemy, aby funkcja wyrzuciła błąd, jeśli <audio> jest niezdefiniowana; i nie chcemy używać try ... catch do obsługi ewentualnych błędów (ponieważ są one brutto); a także nie chcemy używać sprawdzania wewnątrz funkcji, które nie będzie konsekwentnie ujawniać prawdy o tej funkcji (na przykład, {28]} nadal będzie tworzyć element o nazwie <audio>, nawet jeśli HTML5 <audio> nie jest obsługiwane).


Oto trzy podejścia:

// this won't tell us anything about HTML5 `<audio>` as a feature
var foo = function(tag, atr) { return document.createElement(tag)[atr]; }

// this won't return true if the feature is detected (although it works just fine)
var bar = function(tag, atr) { return !document.createElement(tag)[atr]; }

// this is the concise, feature-detecting solution we want
var baz = function(tag, atr) { return !!document.createElement(tag)[atr]; }

foo('audio', 'preload'); // returns "auto"
bar('audio', 'preload'); // returns false
baz('audio', 'preload'); // returns true

Każda funkcja przyjmuje argument dla <tag> i attribute do szukania, ale każda zwraca różne wartości na podstawie tego, co określają porównania.

Ale czekaj, to nie wszystko!

Niektórzy z Was zapewne zauważyli, że w tym konkretnym przykładzie można po prostu sprawdzić właściwość za pomocą nieco bardziej wydajny sposób sprawdzania, czy obiekt w pytanie ma nieruchomość. Można to zrobić na dwa sposoby:]}

// the native `hasOwnProperty` method
var qux = function(tag, atr) { return document.createElement(tag).hasOwnProperty(atr); }

// the `in` operator
var quux = function(tag, atr) { return atr in document.createElement(tag); }

qux('audio', 'preload');  // returns true
quux('audio', 'preload'); // returns true

Dygresja...

Jakkolwiek rzadkie mogą być te sytuacje, może istnieć kilka scenariuszy, w których najbardziej zwięzły, najbardziej wydajny, a tym samym najbardziej preferowany sposób uzyskania true z nie-boolowskiej, prawdopodobnie niezdefiniowanej wartości jest rzeczywiście za pomocą !!. Mam nadzieję, że to absurdalnie to wyjaśni.

 134
Author: Benny,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-22 23:45:27

!! konwertuje wartość na prawo od niej do jej równoważnej wartości logicznej. (Pomyśl biedak 'S sposób" Typ-casting"). Jej intencją jest zwykle przekazanie czytelnikowi, że kod nie obchodziJaka jest wartość w zmiennej, ale jaka jest "prawda" .

 89
Author: Crescent Fresh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-10 17:26:53

!!foo stosuje operator uniary not dwa razy i jest używany do cast do typu boolean, podobnie jak użycie uniary plus {[2] } do cast do number i łączenia pustego ciągu ''+foo do cast do string.

Zamiast tych hacków, możesz również użyć funkcji konstruktora odpowiadających prymitywnym typom (bez używając new) do jawnego rzucania wartości, czyli

Boolean(foo) === !!foo
Number(foo)  === +foo
String(foo)  === ''+foo
 61
Author: Christoph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-10 21:15:16

Tyle odpowiedzi robi połowę roboty. TAK, !!X może być odczytane jako " prawdziwość X [reprezentowana jako wartość logiczna]". Ale !! nie jest, praktycznie rzecz biorąc, tak ważne, aby dowiedzieć się, czy pojedyncza zmienna jest (lub nawet jeśli wiele zmiennych jest) prawdziwe lub fałszywe. !!myVar === true jest tym samym co myVar. Porównywanie !!X do "prawdziwego" logicznego nie jest zbyt użyteczne.

To, co zyskujesz dzięki !!, to możliwość sprawdzenia prawdziwości wielu zmiennych względem siebie w powtarzalna, standaryzowana (i przyjazna dla Jslinta) Moda.

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 przypadku dla odlewania zmiennej do boolean, a następnie porównanie do" true " boolean.

Zobacz " = = i != "z jslint' s directions (Uwaga: Crockford przesuwa nieco swoją stronę; że link w pewnym momencie może umrzeć) na trochę po co:

The == and != operatory wykonują Typ przymusu przed porównaniem. Jest to złe, ponieważ powoduje, że' \T\r\n ' = = 0 jest prawdziwe. Może to maskować błędy typu. JSLint nie może wiarygodnie określić, czy == jest używany poprawnie, więc najlepiej nie używać = = and != w ogóle i zawsze używać bardziej niezawodne = = = i != = operatory zamiast.

Jeśli zależy Ci tylko na tym, że wartość jest prawdziwa lub fałszywa, użyj krótkiej formy. Zamiast z
(foo != 0)

Po Prostu powiedz
(foo)

I zamiast
(foo == 0)

Powiedz
(!foo)

Zauważ, że istnieją pewne nieintuicyjne przypadki , w których wartość logiczna będzie rzucana na liczbę (true jest rzucana na 1 i false na {22]}) podczas porównywania wartości logicznej do liczby. W tym przypadku, !! może być mentalnie użyteczne. Chociaż, ponownie, są to przypadki, w których porównujesz nie-boolean do hard-typed boolean, który jest, imo, a poważny błąd. if (-1) to wciąż jest droga do tego miejsca.

╔═══════════════════════════════════════╦═══════════════════╦═══════════╗
║               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
╚═══════════════════════════════════════╩═══════════════════╩═══════════╝
I wszystko staje się jeszcze bardziej szalone w zależności od silnika. WScript, na przykład, wygrywa nagrodę.
function test()
{
    return (1 === 1);
}
WScript.echo(test());

Z powodu niektórych historycznych okien jive , który wyświetli -1 w polu wiadomości! Spróbuj w cmd.exe prompt i zobacz! Ale WScript.echo(-1 == test()) nadal daje 0, lub WScript false. Odwróć wzrok. To ohydne.

Porównanie prawdziwości:)

Ale co jeśli mam dwie wartości, które muszę sprawdź, czy nie ma takiej samej prawdy/fałszu?

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ść falsy".)

Więc jedynym miejscem, gdzie naprawdę potrzebujesz użyć "boolean-cast variables" byłoby, gdybyś miał sytuację, w której sprawdzasz, czy obie zmienne majątę samą prawdziwość, prawda? To znaczy, użyj !! jeśli potrzebujesz aby sprawdzić, czy dwa vary są prawdziwymi lub fałszywymi (lub nie), to znaczy równymi (lub nie) prawdziwymi.

Nie mogę wymyślić wielkiego, nie wymyślonego przypadku użycia 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 prawdziwe imię i nazwisko małżonka i wiek, możesz kontynuować. W przeciwnym razie masz tylko jedno pole z wartością (lub bardzo wcześnie zaaranżowane małżeństwo) i musisz stworzyć dodatkowy błąd w kolekcji errorObjects.

EDIT 24 paź 2017:

Biblioteki innych firm, które oczekują jawnych wartości logicznych

Oto interesująca sprawa... !! może być użyteczne, gdy biblioteki stron trzecich oczekują jawnych wartości logicznych.

Na przykład, False w JSX (React) ma specjalne znaczenie , które nie jest wyzwalane na prostym falsiness. Jeśli próbowałeś zwrócić coś takiego jak poniżej w swoim 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ć false, aby JSX nie renderował. Powyższe polecenie zwraca 0, które JSX z radością renderuje, tak jak powinno. Nie można powiedzieć, że nie masz Count: {messageCount && <div>Get your count to zero!</div>} (lub coś mniej wymyślonego).

  • Jedna poprawka dotyczy bangbang, który zmusza 0 do !!0, czyli false:
    {!!messageCount && <div>You have messages!</div>}

  • JSX " Docs suggest you bądź bardziej wyraźny, napisz samokomentujący kod i użyj porównania, aby wymusić użycie logiki logicznej.
    {messageCount > 0 && <div>You have messages!</div>}

  • Bardziej komfortowo radzę sobie z falsiness z trójnikiem --
    {messageCount ? <div>You have messages!</div> : false}

Należy pamiętać, że to jest konwencją JSX , a nie nieodłączną częścią JavaScript.

Ale jeśli widzisz dziwne 0s w renderowanym JSX, pomyśl o luźnym fałszywym zarządzaniu.

 52
Author: ruffin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-24 15:30:25

To tylko operator logiczny NOT, dwa razy-służy do konwersji czegoś na boolean, np.:

true === !!10

false === !!0
 47
Author: Greg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-24 08:18:49

Konwertuje sufiks na wartość logiczną.

 29
Author: Paul McMillan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-29 21:22:40

To Podwójna operacja. Pierwsza ! zamienia wartość na wartość logiczną i odwraca jej wartość logiczną. Druga ! Odwraca wartość logiczną z powrotem.

 23
Author: Bill the Lizard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-10 17:28:46

Symuluje zachowanie funkcji odlewania Boolean(). Pierwsza NOT Zwraca wartość logiczną bez względu na to, jaki zostanie podany parametr. Druga NOT neguje tę wartość Boolean, a więc daje true wartość logiczną zmiennej. Wynik końcowy jest taki sam jak przy użyciu funkcji Boolean() Na wartości.

 21
Author: Prakash,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-23 11:53:45

Wygląda na to, że operator !! skutkuje podwójną negacją.

var foo = "Hello World!";

!foo // Result: false
!!foo // Result: true
 19
Author: Steve Harrison,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-09 10:35:33

! jest "boolean not", co zasadniczo typuje wartość "enable" do jej booleanowego przeciwieństwa. Drugi ! odwraca tę wartość. Tak więc !!enable oznacza "nie włączać", co daje wartość enable jako wartość logiczna.

 17
Author: Annika Backstrom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-10 17:29:18

Myślę, że warto wspomnieć, że warunek połączony z logicznym i/lub nie zwróci wartości logicznej, ale ostatni sukces lub pierwsza porażka w przypadku & & i pierwszy sukces lub ostatnia porażka w przypadku / / łańcucha warunków.

res = (1 && 2); // res is 2
res = (true && alert) // res is function alert()
res = ('foo' || alert) // res is 'foo'

W celu oddania warunku do prawdziwego literału boolowskiego możemy użyć podwójnej negacji:

res = !!(1 && 2); // res is true
res = !!(true && alert) // res is true
res = !!('foo' || alert) // res is true
 16
Author: GreQ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-25 10:18:34

Konstrukt !! jest prostym sposobem przekształcania dowolnego wyrażenia JavaScript w jego Boolowski odpowiednik.

Na przykład: !!"he shot me down" === true i !!0 === false.

 13
Author: Navin Rauniyar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-10 08:20:11

To nie jeden operator, tylko dwa. Jest odpowiednikiem poniższego i jest szybkim sposobem na oddanie wartości do wartości logicznej.

val.enabled = !(!enable);
 11
Author: Justin Johnson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-10 21:19:09

Podejrzewam, że to resztki z C++ , gdzie ludzie nadpisują ! operator, ale nie operator bool.

Więc aby uzyskać negatywną (lub pozytywną) odpowiedź w takim przypadku trzeba najpierw użyć ! operator, aby uzyskać boolean, ale jeśli chcesz sprawdzić pozytywny przypadek będzie używać !!.

 9
Author: Darren Clark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-24 08:33:39

Instrukcje if i while oraz operator ? używają wartości prawdy do określenia, która gałąź kodu ma zostać uruchomiona. Na przykład liczby zero i NaN oraz pusty łańcuch są fałszywe, ale inne liczby i łańcuchy są prawdziwe. Obiekty są prawdziwe, ale wartość niezdefiniowana i null są fałszywe.

Operator podwójnej negacji !! oblicza wartość rzeczywistą wartości. W rzeczywistości są to dwa operatory, gdzie !!x oznacza !(!x) i zachowuje się następująco:

  • Jeśli x jest wartość false, !x to true, a !!x to false.
  • Jeśli x jest wartością rzeczywistą, !x jest false, a !!x jest true.

Gdy jest używany na najwyższym poziomie kontekstu logicznego (if, while, lub ?), operator !! jest behawioralnie nie-op. na przykład if (x) i if (!!x) oznaczają to samo.

Praktyczne zastosowania

Ma jednak kilka praktycznych zastosowań.

Jednym z zastosowań jest losowe kompresowanie obiektu do jego wartości prawdy, tak aby Twój kod nie był trzymanie odniesienia do dużego obiektu i utrzymywanie go przy życiu. Przypisanie !!some_big_object do zmiennej zamiast some_big_object pozwala przejść do garbage collector. Jest to przydatne w przypadkach, w których występuje obiekt lub wartość false, np. null lub wartość niezdefiniowana, np. wykrywanie funkcji przeglądarki.

Innym zastosowaniem, o którym wspomniałem w odpowiedzi na temat odpowiadającego mu operatora !! , jest użycie narzędzi "lint", które szukają typowych literówek i diagnostyki wydruków. Na przykład w obu C w języku JavaScript, kilka typowych literówek dla operacji logicznych tworzy inne zachowania, których wynik nie jest taki sam jak Boolean: {]}

  • if (a = b) jest przypisaniem, po którym następuje użycie wartości prawdy b; if (a == b) jest porównaniem równości.
  • if (a & b) jest bitowym i; if (a && b) jest logicznym i. 2 & 5 jest 0 (wartość false); 2 && 5 jest prawdą.

Operator !! zapewnia narzędzie lint, że to, co napisałeś, jest tym, co miałeś na myśli: zrób tę operację, a następnie weź prawdę wartość wyniku.

Trzecim zastosowaniem jest wytworzenie logicznego XOR i logicznego XNOR. W C i JavaScript a && b wykonuje logiczne AND (true, jeśli obie strony są prawdziwe), a a & b wykonuje bitowe AND. a || b wykonuje logiczne OR (true, jeśli przynajmniej jedno z nich jest prawdziwe), a a | b wykonuje bitowe OR. Istnieje bitowy XOR (exclusive OR) jako a ^ b, ale nie ma wbudowanego operatora dla logicznego XOR (true, jeśli dokładnie jedna strona jest prawdziwa). Możesz na przykład zezwolić użytkownikowi na wejście tekst w dokładnie jednym z dwóch pól. To, co możesz zrobić, to przekonwertować każdy na wartość prawdy i porównać je: !!x !== !!y.
 8
Author: Damian Yerrick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-06 14:46:50

Podwójna negacja logiczna. Często używany do sprawdzania, czy wartość nie jest niezdefiniowana.

 7
Author: Sergey Ilinsky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-02 20:21:14

Mnóstwo świetnych odpowiedzi tutaj, ale jeśli przeczytałeś tak daleko, to pomogło mi to "dostać". Otwórz konsolę w Chrome (etc) i zacznij pisać:

!(!(1))
!(!(0))
!(!('truthy')) 
!(!(null))
!(!(''))
!(!(undefined))
!(!(new Object())
!(!({}))
woo = 'hoo'
!(!(woo))
...etc, etc, until the light goes on ;)

Oczywiście, to wszystko to samo, co zwykłe pisanie !!coś, ale dodane nawiasy mogą sprawić, że będzie to bardziej zrozumiałe.

 7
Author: Warren Davis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-24 13:05:49

!!x jest skrótem od Boolean(x)

Pierwszy huk zmusza silnik js do uruchomienia Boolean(x), ale ma również efekt uboczny odwrócenia wartości. Więc drugi huk odwraca efekt uboczny.

 7
Author: Greg0,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-04 12:50:49

!! używa operacji NOT dwa razy razem, ! Przelicz wartość na boolean i odwróć ją, Oto prosty przykład, aby zobaczyć, jak działa !!:

Na początku masz miejsce:

var zero = 0;

Następnie robisz !0, zostanie przekonwertowana na wartość logiczną i zostanie oceniona na true, ponieważ 0 jest falsy, więc otrzymujesz odwróconą wartość i przekonwertowaną na wartość logiczną, więc zostanie oceniona na true.

!zero; //true

Ale nie chcemy odwróconej boolowskiej wersji wartości, więc możemy odwróć to jeszcze raz, aby uzyskać nasz wynik! Dlatego używamy innego !.

Zasadniczo, !! Upewnij się, że otrzymujemy wartość logiczną, a nie falsy, true lub string itp...

To tak, jakby używać funkcji Boolean w javascript, ale łatwy i krótszy sposób konwersji wartości na wartość logiczną:

var zero = 0;
!!zero; //false
 5
Author: Alireza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-18 11:10:25

Oto fragment kodu z angular js

var requestAnimationFrame = $window.requestAnimationFrame ||
                                $window.webkitRequestAnimationFrame ||
                                $window.mozRequestAnimationFrame;

 var rafSupported = !!requestAnimationFrame;
Ich intencją jest ustawienie rafSupported na true lub false w oparciu o dostępność funkcji w requestAnimationFrame

Można to osiągnąć, sprawdzając ogólnie w następujący sposób:

if(typeof  requestAnimationFrame === 'function')
rafSupported =true;
else
rafSupported =false;

Krótka droga może się przydać !!

rafSupported = !!requestAnimationFrame ;

Więc jeśli requestAnimationFrame miał przypisaną funkcję wtedy !requestAnimationFrame byłby fałszywy i jeszcze jeden ! of it would be true

Jeśli requestAnimationFrame był assinged undefined then !requestAnimationFrame byłby prawdziwy i jeszcze jeden ! of it would be false

 4
Author: JeevanReddy Avanaganti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-04 08:25:35

Niektóre operatory w JavaScript wykonują konwersje typu implicit i są czasami służy do konwersji typu.

Operator uniary ! konwertuje swój operand na boolean i neguje go.

Ten fakt prowadzi do następującego idiomu, który możesz zobaczyć w swoim kodzie źródłowym:

!!x // Same as Boolean(x). Note double exclamation mark
 3
Author: GibboK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-01 07:29:12

Zwraca wartość logiczną zmiennej.

Zamiast tego można użyć klasy Boolean.

(proszę przeczytać opisy kodu)

var X = "test"; // X value is "test" as a String value
var booleanX = !!X // booleanX is `true` as a Boolean value beacuse non-empty strings evaluates as `true` in boolean
var whatIsXValueInBoolean = Boolean(X) // whatIsXValueInBoolean is `true` again
console.log(Boolean(X) === !!X) // writes `true`

Mianowicie, Boolean(X) = !!X w użyciu.

Proszę sprawdzić fragment kodu poniżej

let a = 0
console.log("a: ", a) // writes a value in its kind
console.log("!a: ", !a) // writes '0 is NOT true in boolean' value as boolean - So that's true.In boolean 0 means false and 1 means true.
console.log("!!a: ", !!a) // writes 0 value in boolean. 0 means false.
console.log("Boolean(a): ", Boolean(a)) // equals to `!!a`
console.log("\n") // newline

a = 1
console.log("a: ", a)
console.log("!a: ", !a)
console.log("!!a: ", !!a) // writes 1 value in boolean
console.log("\n") // newline

a = ""
console.log("a: ", a)
console.log("!a: ", !a) // writes '"" is NOT true in boolean' value as boolean - So that's true.In boolean empty strings, null and undefined values mean false and if there is a string it means true.
console.log("!!a: ", !!a) // writes "" value in boolean
console.log("\n") // newline

a = "test"
console.log("a: ", a) // writes a value in its kind
console.log("!a: ", !a)
console.log("!!a: ", !!a) // writes "test" value in boolean

console.log("Boolean(a) === !!a: ", Boolean(a) === !!a) // writes true
 3
Author: efkan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-11 07:22:44
a = 1;
alert(!a) // -> false : a is not not defined
alert(!!a) // -> true : a is not not defined

Dla !a sprawdza, czy a jest zdefiniowana Nie, podczas gdy !!a sprawdza, czy zmienna jest zdefiniowana.

!!a jest tym samym co !(!a). Jeśli a jest zdefiniowane, a jest true, !a jest false i !!a jest true.

 2
Author: user3698272,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-28 03:35:13

Użyj operatora logicznego not dwa razy
to znaczy !true = false
i !!true = true

 2
Author: Abhay Dixit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-15 10:25:01

Po obejrzeniu tych wszystkich wspaniałych odpowiedzi, chciałbym dodać kolejny powód do używania !!. Currenty pracuję w Angular 2-4 (TypeScript) i chcę zwrócić wartość logiczną jako false, gdy mój użytkownik nie jest uwierzytelniony. Jeśli nie jest uwierzytelniony, token-string będzie null lub "". Mogę to zrobić używając następnego bloku kodu:

public isAuthenticated(): boolean {
   return !!this.getToken();
}
 2
Author: Wouter Vanherck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-29 07:15:21

!! jest podobny do korzystania z konstruktor Boolean, lub prawdopodobnie bardziej jak funkcja Boolean.

console.log(Boolean(null)); // Preffered over the Boolean object

console.log(new Boolean(null).valueOf()); // Not recommended for coverting non-boolean values

console.log(!!null); // A hacky way to omit calling the Boolean function, but essentially does the same thing. 


// The context you saw earlier (your example)
var vertical;

function Example(vertical)
{
        this.vertical = vertical !== undefined ? !!vertical : 
        this.vertical; 
        // Let's break it down: If vertical is strictly not undefined, return the boolean value of vertical and set it to this.vertical. If not, don't set a value for this.vertical (just ignore it and set it back to what it was before; in this case, nothing).   

        return this.vertical;
}

console.log( "\n---------------------" )

// vertical is currently undefined

console.log(new Example(vertical).vertical); // The falsey or truthy value of this.vertical
console.log(!!new Example(vertical).vertical); // Coerced value of this.vertical

vertical = 12.5; // set vertical to 12.5, a truthy value.
console.log(new Example(vertical).vertical); // The falsey or truthy value of this.vertical which happens to be true anyway
console.log(!!new Example(vertical).vertical); // Coerced value of this.vertical

vertical = -0; // set vertical to -0, a falsey value.
console.log(new Example(vertical).vertical); // The falsey or truthy value of this.vertical which happens to be false either way
console.log(!!new Example(vertical).vertical); // Coerced value of this.vertical

wartości false w javascript wymuszają na false i prawdziwe wartości przymus do true. wartości false i truthy mogą być również używane w poleceniach if i zasadniczo "mapują" do odpowiadającej im wartości logicznej. Jednak prawdopodobnie będziesz nie musisz często używać odpowiednich wartości logicznych, ponieważ w większości różnią się one pod względem wyjścia (wartości zwracanych).

Chociaż może to wydawać się podobne do odlewania, realistycznie jest to prawdopodobnie zwykły przypadek i nie jest "zbudowany" lub celowo stworzony dla i jak boolean Obsada. Więc nie nazywajmy tego tak.

Dlaczego i jak to działa

Aby być zwięzłym, wygląda to mniej więcej tak: ! ( !null ). Natomiast nulljest false , więc !null byłoby true . Wtedy !true byłoby false i zasadniczo odwróciłoby się do tego, co było wcześniej, poza tym razem jako właściwa wartość logiczna (lub nawet odwrotnie z prawdziwymi wartościami Jak {} lub 1).


Wracając do twojego przykładu

Ogólnie rzecz biorąc, kontekst, który widziałeś, dostosowuje się po prostu this.vertical w zależności od tego, czy vertical jest zdefiniowany, a jeśli tak, zostanie ustawiony na wynik wartość logiczna pionowa, w przeciwnym razie nie zmieni się. Innymi słowy, jeśli vertical jest zdefiniowana; this.vertical zostanie ustawiona na wartość logiczną, w przeciwnym razie pozostanie taka sama. Myślę, że to samo w sobie jest przykładem tego, jak byś użył !!, i co to robi.


Przykład Wejścia/Wyjścia Pionowego

Uruchom ten przykład i pokręć się z pionową wartością na wejściu. Zobacz, do czego zmusza wynik, abyś mógł w pełni zrozumieć kod kontekstu. In the input, wprowadź dowolną poprawną wartość javascript. pamiętaj, aby dołączyć cytaty, jeśli testujesz ciąg znaków. Nie przejmuj się zbytnio kodem CSS i HTML, po prostu uruchom ten fragment i baw się nim. Warto jednak przyjrzeć się kodowi javascript niezwiązanemu z DOM (użycie przykładowego konstruktora i zmiennej pionowej).

var vertical = document.getElementById("vertical");
var p = document.getElementById("result");

function Example(vertical)
{
        this.vertical = vertical !== undefined ? !!vertical : 
        this.vertical;   

        return this.vertical;
}

document.getElementById("run").onclick = function()
{

  p.innerHTML = !!( new Example(eval(vertical.value)).vertical );
  
}
input
{
  text-align: center;
  width: 5em;
} 

button 
{
  margin: 15.5px;
  width: 14em;
  height: 3.4em;
  color: blue;
}

var 
{
  color: purple;
}

p {
  margin: 15px;
}

span.comment {
  color: brown;
}
<!--Vertical I/O Example-->
<h4>Vertical Example</h4>
<code id="code"><var class="var">var</var> vertical = <input type="text" id="vertical" maxlength="9" />; <span class="comment">// enter any valid javascript value</span></code>
<br />
<button id="run">Run</button>
<p id="result">...</p>
 2
Author: WEB_UI,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-17 16:32:12

Zmusza wszystkie rzeczy do logicznego myślenia.

Na przykład:

console.log(undefined); // -> undefined
console.log(!undefined); // -> true
console.log(!!undefined); // -> false

console.log('abc'); // -> abc
console.log(!'abc'); // -> false
console.log(!!'abc'); // -> true

console.log(0 === false); // -> undefined
console.log(!0 === false); // -> false
console.log(!!0 === false); // -> true
 2
Author: Khuong,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-06 02:02:50