Kas tai yra !! (ne) operatorius javascript?

Matė, kad operatorius naudoja kodą, kuris nepripažįstamas kaip du šauktukai, pavyzdžiui: !! . Ar kas nors gali man pasakyti, ką šis operatorius daro?

Kontekstas, kuriame aš mačiau tai buvo

 this.vertical = vertical !== undefined ? !!vertical : this.vertical; 
2586
24 апр. Hexagon teorija nustatyta 24 Bal 2009-04-24 11:13 '09, 11:13, 2009-04-24 11:13
@ 34 atsakymai
  • 1
  • 2

oObject į boolean. Jei jis buvo klaidingas (pvz., 0, null , undefined ir tt), tai bus false , kitaip true .

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

Taigi !! ne operatorius, tai tik operatorius ! du kartus.

Realaus pasaulio pavyzdys „Test IE Version“:

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

Jei ⇒

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

bet jei jūs ⇒

 console.log(!!navigator.userAgent.match(/MSIE 8.0/)); // returns true or false 
2315
24 апр. atsakė stevehipwellui balandžio 24 d 2009-04-24 11:18 '09, 11:18, 2009-04-24 11:18

Tai baisiai neaiškus būdas atlikti tipo konvertavimą.

! NE Taigi !true - false , ir !false !0 - true , ir !1 - false .

border=0

Taigi jūs konvertuojate vertę į logišką, tada apverskite ir vėl apverskite.

 // Maximum Obscurity: val.enabled = !!userId; // Partial Obscurity: val.enabled = (userId != 0) ? true : false; // And finally, much easier to understand: val.enabled = (userId != 0); 
780
10 сент. Atsakyti Tom Ritter 10 rugsėjis 2009-09-10 20:28 '09 ne 20:28 2009-09-10 20:28

!!expr grąžina loginę vertę ( true arba false ), priklausomai nuo išraiškos tikimybės. Tai prasminga, kai naudojama ne nulinės rūšies. Apsvarstykite šiuos pavyzdžius, ypač trečiąjį pavyzdį ir toliau:

  !!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! 
408
15 мая '12 в 12:06 2012-05-15 12:06 atsakymas duotas Salmanui gegužės 15 d., 12 val. 12:06 2012-05-05 12:06

Užvirinkite arbatą:

!! ne operatorius. Tai dvigubas naudojimas ! - tai yra logiškas „ne“ operatorius.


Teoriškai:

! nustato, kas nėra vertė:

  • Tiesa ta, kad false (todėl rezultatai yra true )

  • Tiesa ta, kad true nėra false (kodėl !true rezultatai yra false )


!! apibrėžia „tiesą“ apie tai, kas nėra:

  • Tiesa ta, kad true true (todėl !!true true )

  • Tiesa ta, kad false nėra false (todėl false priemonė yra false )


Ką mes norime nustatyti lyginant yra „tiesą“ apie nuorodos reikšmę, o ne saitos vertę. Yra precedentas, kur mums gali tekti žinoti tiesą apie vertę, net jei tikimės, kad vertė bus false (arba falsey), arba jei tikimės, kad vertė nebus boolean .


Praktiškai:

Apsvarstykite trumpą funkciją, kuri aptinka funkcionalumą (ir šiuo atveju suderinamumą su platforma) naudojant dinaminį įvestį (dar vadinamą „ančių“). Norime parašyti tikrą funkciją, jei naudotojo naršyklė palaiko HTML5 <audio> elementą, tačiau nenorime, kad funkcija suteiktų klaidą, jei <audio> neapibrėžta; ir mes nenorime naudoti try ... catch bet kokias galimas klaidas (nes jos yra grubus); ir nenorime naudoti čekio funkcijoje, kuri nuolat nerodys tiesos apie šią funkciją (pavyzdžiui, document.createElement('audio') vis tiek sukurs elementą su pavadinimu <audio> , net jei HTML5 <audio> nepalaikomas) .


Štai trys būdai:

 // 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 

Kiekvienai funkcijai reikia <tag> ir attribute ieškoti argumento, tačiau kiekvienas iš jų grąžina kitokią vertę, priklausomai nuo to, ką apibūdina.

Bet palaukite, dar daugiau!

Kai kurie iš jūsų galbūt pastebėjote, kad šiame konkrečiame pavyzdyje galite tiesiog patikrinti turtą naudodami šiek tiek veiksmingesnę priemonę, kad patikrintumėte, ar aptariamas objektas turi nuosavybę. Tai galima padaryti dviem būdais:

 // 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 

Mes išsiblaškome ...

Nesvarbu, kaip retai pasitaiko šių situacijų, gali būti keletas scenarijų, kuriuose glaustiausias, efektyviausias ir todėl labiausiai pageidaujamas būdas gauti true iš nulinės vertės, galbūt neapibrėžtas, tikrai naudojasi !! . Tikiuosi, kad tai juokinga.

139
23 февр. Benny atsakymas, pateiktas vasario 23 d 2013-02-23 02:45 '13, 02:45 am 2013-02-23 02:45

!! konvertuoja vertę į dešinę į lygiavertę loginę vertę. (Pagalvokite, kad jis turi blogą „liejimo“ būdą). Jo tikslas, kaip taisyklė, perduoti skaitytojui, kad kodo nerūpi, kokia vertė yra kintamajame, bet tai yra „tikroji“ vertė .

90
10 сент. Atsakymas pateikiamas Crescent Fresh 10 Sep. 2009-09-10 20:26 '09 ne 20:26 2009-09-10 20:26

!!foo naudoja unary operatorių du kartus ir naudojamas priversti prie loginio tipo, panašaus į unary plus +foo , skaičiuoti ir sujungti tuščią eilutę ''+foo kad jį būtų galima išversti į eilutę.

Vietoj šių hacks jūs taip pat galite naudoti konstruktoriaus funkcijas, atitinkančias primityvius tipus (nenaudojant new ) aiškiai verčių vertei, t.y.

 Boolean(foo) === !!foo Number(foo) === +foo String(foo) === ''+foo 
62
11 сент. Christofo atsakymas rugsėjo 11 d 2009-09-11 00:15 '09 ne 0:15 2009-09-11 00:15

Tiek daug atsakymų atlieka pusę darbo. Taip, !!X gali būti skaitoma kaip „X [tiesa“ yra pavaizduota kaip loginė vertė]. Bet !! Tiesą sakant, ne taip svarbu išsiaiškinti, ar vienas kintamasis (ar net daugybė kintamųjų) yra teisingas ar klaidingas. !!myVar === true yra tas pats, kas myVar . Lyginant „ !!X su „tikra“ logine verte, nėra labai naudinga.

Ką gausite su !! tai yra gebėjimas patvirtinti kelis kintamuosius vienas prieš kitą pakartojamu, standartizuotu (ir JSLint draugišku) būdu.

Tiesiog liejimas :(

Tai yra ...

  • 0 === false yra false .
  • !!0 === false true .

Aukščiau pateikta informacija nėra labai naudinga. if (!0) duoda tuos pačius rezultatus kaip if (!!0 === false) . Aš negaliu galvoti apie gerą atvejį, kai kintamasis būtų perkeliamas į logišką, o po to lyginamas su „tikra“ logine verte.

Žr. „== ir! =“ JSLint kryptyse (pastaba: „Crockford“ šiek tiek perkelia savo svetainę; tam tikru momentu ši nuoroda gali mirti), kad sužinotumėte, kodėl:

Operatoriai == ir! = Atlikite tipo konvertavimą prieš palyginimą. Tai yra blogai, nes tai reiškia, kad „r“ yra == 0. Tai gali maskuoti tipo klaidas. JSLint negali patikimai nustatyti, ar == naudojamas teisingai, todėl geriausia nenaudoti == ir! = Ir visuomet naudokite patikimesnius operatorius === ir! ==.

Jei jums rūpi tik tai, kad vertė yra teisinga arba klaidinga, naudokite trumpą formą. Vietoj
(foo != 0)

tiesiog pasakyti
(foo)

ir vietoj to
(foo == 0)

pasakyti
(!foo)

Atkreipkite dėmesį, kad yra keletas ne intuityvių atvejų, kai loginė vertė bus sumažinta iki skaičiaus ( true iki 1 ir false iki 0 ), lyginant loginę vertę su skaičiumi. Šiuo atveju !! gali būti psichiškai naudingas. Nors ir vėl, tai yra atvejai, kai lyginate ne loginę vertę su griežta loginės vertės rūšimi, kuri, mano nuomone, yra rimta klaida. if (-1) yra čia.

 ╔═══════════════════════════════════════╦═══════════════════╦═══════════╗ ║ 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 ╚═══════════════════════════════════════╩═══════════════════╩═══════════╝ 

Ir viskas priklauso nuo jūsų variklio. Pavyzdžiui, „WScript“ laimi prizą.

 function test() { return (1 === 1); } WScript.echo(test()); 

Dėl kai kurių istorinių „Windows“ versijų pranešimo lauke bus rodoma -1! Išbandykite cmd.exe komandų eilutėje ir pamatykite! Tačiau WScript.echo(-1 == test()) vis dar grąžina 0 arba WScript yra false . Pasukite aplink. Tai yra bjaurus.

Tiesos palyginimas :)

Bet ką daryti, jei turiu dvi vertybes, kurias reikia patikrinti dėl tos pačios tiesos / apgaulės?

myVar1 = 0; kad mes turime myVar1 = 0; ir myVar2 = undefined; ,

  • myVar1 === myVar2 yra 0 === undefined ir, žinoma, yra klaidinga.
  • !!myVar1 === !!myVar2 yra !!0 === !!undefined ir tai tiesa! Tas pats teisingumas! (Šiuo atveju abu „turi melagingą tiesą“.)

Taigi, vienintelė vieta, kur tikrai reikia naudoti „loginius transformacijos kintamuosius“, yra, jei turėjote situaciją, kai tikrinate, ar abu kintamieji turi tą pačią tiesą, tiesa? Tai yra, naudokite jį !! jei reikia pamatyti, ar šie du kintamieji yra teisingi ar klaidingi (ar ne), tai yra, lygūs (ar ne) teisingumas.

Aš negaliu pagalvoti apie kitą, nesudėtingą naudojimo atvejį. Galbūt formoje yra „susijusių“ laukų?

 if (!!customerInput.spouseName !== !!customerInput.spouseAge ) { errorObjects.spouse = "Please either enter a valid name AND age " + "for your spouse or leave all spouse fields blank."; } 

Taigi, jei sutuoktiniui yra teisingas ar klaidingas vardas ir amžius, galite tęsti. Priešingu atveju, turite tik vieną lauką, kurio vertė (arba labai ankstyva santuoka), ir turite sukurti papildomą klaidą savo klaidų errorObjects rinkinyje.


EDIT 2017 m. Spalio 24 d., Vasario 6 d.

Trečiųjų šalių bibliotekos, kurios tikisi aiškių loginių vertybių

Čia yra įdomus atvejis ... !! Tai gali būti naudinga, kai trečiosios šalies bibliotekos tikisi aiškių loginių vertybių.

Pavyzdžiui, „ False“ JSX („React“) turi ypatingą reikšmę, kurią sukelia paprastas melas. Jei JSX bandėte grąžinti kažką panašaus į tokį, laukite int in messageCount ...

{messageCount <div>You have messages!</div>}

... galite nustebinti, kad React rodo 0 kai neturite pranešimų. Turite aiškiai grąžinti klaidingą, kad JSX nebūtų rodomas. Pirmiau pateiktas pareiškimas grąžina 0 , kurį JSX sėkmingai rodo, kaip turėtų būti. Jis negali pasakyti, kad neturite Count: {messageCount <div>Get your count to zero!</div>} (arba kažką mažiau suburto).

  • Vienas iš pataisymų apima bangbangą, kuris sukelia 0–0, o tai yra false :
    {!!messageCount <div>You have messages!</div>}

  • JSX dokumentai rodo, kad turite būti aiškesni, parašyti savarankiškai pažymėtą kodą ir naudoti palyginimą, kad priverstumėte loginį apdorojimą.
    {messageCount > 0 <div>You have messages!</div>}

  • Man patogiau elgtis su trigubu klaidingumu -
    {messageCount? <div>You have messages!</div>: false}

Tas pats ir „Typescript“: jei turite funkciją, kuri grąžina loginę vertę (arba priskiria reikšmę „Boolean“ kintamajam), jūs [paprastai] negalite grąžinti / priskirti loginės vertės -y; jis turi būti labai įvestas loginis tipas. Tai reiškia, kad jei myObject labai įvestas , return !myObject; veikia funkcijai, kuri grąžina loginę vertę, bet return myObject; ne. Turite return !!myObject kad atitiktų „ return !!myObject “ lūkesčius.

Išimtis spausdinimui? Jei myObject buvo any , grįžtate į „Wild West JavaScript“ ir galite grąžinti ją be !! net jei jūsų grąžinimo tipas yra logiškas.

Atminkite, kad tai yra „JSX“ ir „Typescript“ konvencijos ir nėra būdingos „JavaScript“ .

Bet jei JSX atvaizdavimo metu matote keistą 0 , pagalvokite apie klaidingą valdymą.

55
29 апр. atsakymas pateikiamas ruffin balandžio 29 d 2015-04-29 21:14 '15, 21:14 2015-04-29 21:14

Tai tik logiškas NE operatorius, du kartus - jis naudojamas konvertuoti kažką į loginį, pvz .:

 true === !!10 false === !!0 
49
24 апр. Atsakyti Greg 24 apr. 2009-04-24 11:18 '09, 11:18, 2009-04-24 11:18

Jis konvertuoja priesagą prie loginės vertės.

29
10 сент. Paul McMillan atsakymas rugsėjo 10 d 2009-09-10 20:27 '09 ne 20:27 2009-09-10 20:27

Tai dvigubai not . Pirma ! konvertuoja vertę į loginę reikšmę ir invertuoja jo loginę vertę. Antra ! grąžina grąžinimo vertę.

23
10 сент. Atsakymas, kurį pateikė Bill the Lizard 10 Sep. 2009-09-10 20:28 '09 ne 20:28 2009-09-10 20:28

Jis imituoja funkciją Boolean() liejimą. Pirmasis NOT grąžina loginę vertę, nepriklausomai nuo to, kuriam operandui jis suteiktas. Antrasis NOT neigia Boolean reikšmę ir todėl suteikia true kintamojo vertę. Galutinis rezultatas yra toks pat, kaip naudojant „ Boolean() funkciją.

21
23 марта '11 в 14:53 2011-03-23 14:53 atsakymas suteikiamas „ Prakash“ kovo 23 d., 11 val. 14:53 2011-03-23 ​​14:53

Atrodo, kad operatorius !! veda prie dvigubo neigimo.

 var foo = "Hello World!"; !foo // Result: false !!foo // Result: true 
20
24 апр. Steve Harrison atsakymas, pateiktas balandžio 24 d 2009-04-24 11:20 '09, 11:20, 2009-04-24 11:20

! „boolean not“, kuris iš esmės rodo „įgalinti“ vertę savo loginiame priešingame. Antra! flips šią vertę. Taigi, „ !!enable reiškia „neleisti“, kuris suteikia leidimo reikšmę logiškai.

17
10 сент. Annika Backstrom atsakymas rugsėjo 10 d 2009-09-10 20:29 '09 ne 20:29 2009-09-10 20:29

Manau, verta paminėti, kad sąlyga, susieta su logine IR / ARBA, nebus grąžinta logine verte, bet paskutinė sėkmė ar pirmasis neveikimas, susijęs su taip pat pirmuoju sėkmingumu arba paskutiniu nesėkmės atveju || grandinės sąlygomis.

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

Jei norite taikyti sąlygą tikrajam Būlio žodžiui, galime naudoti dvigubą neigimą:

 res = !!(1  2); // res is true res = !!(true  alert) // res is true res = !!('foo' || alert) // res is true 
16
25 мая '16 в 13:18 2016-05-25 13:18 atsakymą GreQ pateikė gegužės 25 d. 16 d. 13:18 2016-05-25 13:18

Statyba !! yra paprastas būdas paversti bet kurią „JavaScript“ išraišką į savo loginį ekvivalentą.

Pavyzdžiui: !!"he shot me down" === true ir !!0 === false .

13
09 апр. Atsakymas, kurį pateikė Navin Rauniyar 09 Bal 2014-04-09 07:29 '14, 7:29, 2014-04-09 07:29

Tai ne vienas operatorius, tai du. Tai yra lygiavertė šiai reikšmei ir yra greitas būdas pateikti vertę į loginę vertę.

 val.enabled = !(!enable); 
11
11 сент. Atsakymą pateikė Justin Johnson 11 sep. 2009-09-11 00:19 '09 ne 0:19 2009-09-11 00:19

Ar operatoriai ir operatoriai ? naudokite tiesos vertes, kad nustatytumėte, kuris kodo filmas paleisti. Pvz., NaN ir tuščios eilutės nuliniai skaičiai yra klaidingi, bet kiti skaičiai ir eilutės yra teisingos. Objektai yra teisingi, bet neapibrėžti ir null yra klaidingi.

Dvigubo neigimo operatorius !! apskaičiuoja tiesos vertės vertę. Tai iš tikrųjų du operatoriai, kur !!x reiškia !(!x) ir elgiasi taip:

  • Jei x yra neteisinga reikšmė ,! !x yra true ir !!x yra false .
  • Jei x yra tiesa ,! !x yra false , o !!x yra true .

Naudojant viršutiniame lygmenyje loginį kontekstą ( if , while arba ? ) Operator !! elgesys neveikia. Pavyzdžiui, if (x) ir if (!!x) reiškia tą patį.

Praktinis naudojimas

Tačiau ji turi keletą praktinių pritaikymų.

Vienas iš būdų - lengvai suspausti objektą į jo tiesos vertę, kad jūsų kode nebūtų nuorodos į didelį objektą ir išsaugotas. Kintamojo !!some_big_object priskyrimas vietoj some_big_object leidžia some_big_object eiti į šiukšlių surinkėją. Tai naudinga tais atvejais, kai sukuriamas objektas arba neteisinga vertė, pvz., null arba neapibrėžtos vertės, pvz., Naršyklės funkcijos aptikimas.

Kitas naudojimas, kurį minėjau atsakyme apie C-atitinkamą operatorių !! , - tai yra „pūkelių“ įrankiai, kurie ieško bendrų rašmenų ir spausdinimo diagnostikos. Pavyzdžiui, tiek „C“, tiek „JavaScript“, kai kurie įprastiniai klaidų spausdinimo veiksmai, susiję su loginėmis operacijomis, sukuria kitą elgesį, kuris nėra visiškai logiškas:

  • if (a = b) yra užduotis, po kurios naudojama tiesos b vertė; if (a == b) - lygybės palyginimas.
  • if (a b) yra bitų IR; if (a b) yra logiška I. 2 5 - 0 (klaidinga vertė); 2 5 tiesa.

Operatorius !! užtikrina pūkelių įrankį, kad tai, ką parašėte, reiškia tai, ką jūs reiškėte: atlikite šią operaciją, tada paimkite tikrąją rezultato vertę.

Trečiasis naudojimas yra loginio XOR ir loginio XNOR sukūrimas. C ir JavaScript sistemoje a b atlieka loginį IR (tiesa, jei abi pusės yra teisingos), ir a b atlieka bitų IR. a || b a || b atlieka loginį OR (tiesa, jei bent vienas iš jų yra teisingas) ir a | b a | b atlieka bitų OR. Yra bitų XOR (išskirtinis OR) kaip a ^ b , bet nėra loginio XOR operatoriaus (tiesa, jei tik viena pusė yra tiesa). Pavyzdžiui, galite leisti vartotojui įvesti tekstą tik viename iš dviejų laukų. Tai, ką galite padaryti, yra juos paversti tiesa ir palyginti juos: !!x !== !!y .

8
06 марта '16 в 17:46 2016-03-06 17:46 Atsakymą pateikė Damian Yerrick kovo 16 d. 16 d. 17:46 2016-03-06 17:46

Įtariu, kad jis išlieka iš C ++, kur žmonės nepaiso! operatorius, bet ne operatoriaus bool.

Taigi, norint gauti neigiamą (arba teigiamą) atsakymą, šiuo atveju pirmiausia turite naudoti! operatoriui gauti loginę vertę, bet jei norite patikrinti teigiamą atvejį, naudokite !!.

8
24 апр. Darren Clark atsakymas, pateiktas balandžio 24 d 2009-04-24 11:33 '09 11:33 2009-04-24 11:33

!! tai NOT naudoja operaciją du kartus kartu ! konvertuoti vertę į boolean ir invertuokite, čia yra paprastas pavyzdys, kaip pamatyti !! darbai:

Pirmiausia turite vietą:

 var zero = 0; 

Tada jūs darysite !0 , jis bus konvertuojamas į loginę vertę ir bus vertinamas kaip true , nes 0 yra falsy , todėl jūs gaunate grąžinimo vertę ir konvertuojate į loginę vertę, todėl vertinama kaip true .

 !zero; //true 

bet mums nereikia atvirkštinės loginės versijos versijos, kad galėtume dar kartą atšaukti, kad gautume rezultatą! Štai kodėl mes naudojame kitą ! ,

Iš esmės !! įsitikinkite, kad gauname loginę vertę, o ne melagingą, teisingą ar eilutę ir tt

Taigi kaip „ Boolean funkciją naudokite javascript'e, bet paprastu ir trumpu būdu konvertuoti vertę į loginę vertę

 var zero = 0; !!zero; //false 
7
24 июня '17 в 7:16 2017-06-24 07:16 atsakymą Alireza pateikė birželio 17 d. 17, 07:16 2017-06-06 07:16

!!x yra Boolean(x) santrumpa

Pirmasis smūgis sukelia js variklio paleidimą Boolean(x) , bet taip pat turi šalutinį poveikį apverčiant vertę. Taigi antrasis streikas panaikina šalutinį poveikį.

7
04 дек. atsakymas, kurį pateikė Greg Gum 04 dec. 2015-12-04 15:50 '15 15:50 2015-12-04 15:50

Dvigubas loginis neigimas. Dažnai naudojamas neapibrėžtos vertės tikrinimui.

7
02 дек. Sergejo Ilinskio atsakymas 02.12 2010-12-02 23:21 '10, 23:21, 2010-12-02 23:21

Čia yra daug puikių atsakymų, bet jei perskaitėte, tai padėjo man „gauti“. Atidarykite „Chrome“ konsolę (ir tt) ir pradėkite rašyti:

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

Natūralu, kad tai kaip tiesiog rašyti !! someThing, но добавленные скобки могут помочь сделать его более понятным.

7
ответ дан Warren Davis 24 апр. '14 в 16:05 2014-04-24 16:05