Nedir !! JavaScript değil (değil) operatör?


3106

Öyle gibi iki ünlem işareti şeklinde, tanımadığım bir operatör kullanmak gibi görünüyor bazı kodlar gördük: !!. Birisi bana bu operatörün ne yaptığını söyleyebilir mi?

Bunu gördüğüm bağlam,

this.vertical = vertical !== undefined ? !!vertical : this.vertical;

945
"Bang, bang boolean" ile hatırlayın
Gus

75
Sadece kayıt için, burada alıntılananı yapmayın. Yapın if(vertical !== undefined) this.vertical = Boolean(vertical);- olup biten çok daha temiz ve nettir, gereksiz atama gerektirmez, tamamen standarttır ve aynı zamanda (mevcut FF ve Chrome'da) jsperf.com/boolean-conversion-speed kadar hızlıdır .
Phil H

73
!! bir operatör değil. Sadece! operatör iki kez.
Vivek

11
Sadece kayıt için, Boolean(5/0)aynı değil!!5/0
schabluk

63
@schabluk, kayıt için operasyon sırası,!!5/0 ürettiği gibi üretmekten Infinityziyade sebeptir . operatöre göre daha yüksek önceliğe sahip olduğundan - aka - değerine eşdeğerdir . Bir çift patlama kullanarak Booleanize etmek istiyorsanız, kullanmanız gerekir . trueBoolean(5/0)!!5/0(!!5)/0true/0!/5/0!!(5/0)
mat

Yanıtlar:


2745

Çevirir Objectiçin boolean. De (örneğin Falsey olsaydı 0, null, undefinedvs.), bu olacak false, aksi takdirde true.

!oObject  // inverted boolean
!!oObject // non inverted boolean so true boolean representation

Yani !!bu sadece, bir operatör değil !iki kez operatörü.

Gerçek Dünya Örneği "Test IE sürümü":

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

Eğer ⇒

console.log(navigator.userAgent.match(/MSIE 8.0/));  
// returns either an Array or null  

Ama eğer ⇒

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

123
Boole olmayan bir sürümü ters çevrilmiş bir boole'ye dönüştürür (örneğin, 5, JS'de yanlış olmayan bir değer olduğu için! Gerçek olmak).
Chuck

111
Bunu tarif etmenin kolay bir yolu şudur: Boolean (5) === !! 5; Aynı döküm, daha az karakter.
Micah Snyder

39
Bu, doğruluk değerlerini boolean true değerine ve falsy değerlerini de boolean false değerine dönüştürmek için kullanılır.
thetoolman

13
@Micah Snyder, JavaScript'te boolean'ları yeni Boolean () ile kutulayan nesneler oluşturmak yerine boolean ilkellerini kullanmanın daha iyi olduğuna dikkat edin. Farkı görmek için bir örnek: jsfiddle.net/eekbu
victorvartan

4
Bildiğim kadarıyla, bu bang-bang deseni bir if (… _ ifadesi içinde değil, sadece bir boole döndürmesi gereken bir işlevin dönüş ifadesinde yararlı değildir.
rds

854

Bu, bir tür dönüştürme yapmanın korkunç bir yoludur.

!olduğu DEĞİL . Yani !trueolduğunu falseve !falsebir true. !0olduğu trueve !1bir false.

Yani bir değeri bir boole değerine dönüştürür, sonra ters çevirir, sonra tekrar ters çevirirsiniz.

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

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

// And finally, much easier to understand:
val.enabled = (userId != 0);

74
!! yanlış = yanlış. !! true = true
cllpse

89
"Anlaması çok daha kolay" varyantı burada anlamak gerçekten daha mı kolay? 0'a karşı denetim, 0'a karşı gerçek bir denetim değildir, ancak Javascript'in 0'a eşit olduğunu düşündüğü garip değerler listesine karşı yapılan bir denetim userId ? true : false , dönüşümün devam ettiğini daha açık hale getirir ve userId'ın değerinin açıkça ayarlanmış olabileceği durumu ele alırundefined
Ben Regenspan

54
Beynim deşifre herhangi bir sorun yoktur !!variçine Boolean(var).. ve !!alternatiflere göre daha hızlı (daha az süreçte talimatlar); kısadır.
adamJLev

7
@RickyClarkson esas olarak okunabilirlik içindir çünkü sözdizimsel olarak gerekli değildir. Bazıları her zaman bir koşulun parantez içine alınması ifadesini ifadenin geri kalanından ayırmak için kullanır.
Dave Rager

8
Buna katılmıyorum. userId != 0için de geçerlidir null, NaNve undefinedfakat sahte false. Tam olarak bu davranışı istiyorsanız, muhtemelen bu konuda açık olmalısınız. Ama tam olarak aynı çalıştı bile !!userId, ister açık değil istemek bu değerler ya da sadece JavaScript'ın tip dönüştürme kurallarını dikkate almak başarısız olsun, buraya false gelip.
philh

449

!!exprifadenin gerçekliğine bağlı olarak bir Boole değeri ( trueveya false) döndürür . Boole olmayan türlerde kullanıldığında daha mantıklıdır. Bu örnekleri, özellikle de 3. örneği ve sonrasını düşünün:

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

63
Kayda değer:!!new Boolean(false) // true
Camilo Martin

43
... Ama aynı zamanda!!Boolean(false) // false
Camilo Martin

97
new Boolean(false)bir cisimdir ve falsili bir değer içeriyor olsa bile cisim doğrudur!
Salman A

3
Evet biliyorum, ama (çoğu yerli kurucular gerçeğini göz önünde String, Number, Date, vs) çok fonksiyonları olarak çağrılabilir olmak içindir, henüz bu durumda sonuç farklıdır!
Camilo Martin

4
@CamiloMartin: farkettim o new Boolean(false)döner bir objectsüre Boolean(false)döner ilkel false . Umarım bu mantıklıdır.
Salman A

155

Biraz çay demleyin:

!!bir operatör değil. !Mantıksal "değil" operatörünün - çift ​​kullanımıdır .


Teoride:

! bir değerin ne olmadığının "gerçeğini" belirler:

  • Gerçek şu ki falsedeğil true(bu yüzden !falsesonuçlanır true)

  • Gerçek şu ki truedeğil false(bu yüzden !truesonuçlanır false)


!!bir değerin ne olmadığının "gerçeğini" belirler :

  • Gerçek şu ki truedeğil değil true (en bu yüzden !!truesonuçlanır true)

  • Gerçek şu ki falsedeğil değil false (en bu yüzden !!falsesonuçlanır false)


Karşılaştırmada belirlemek istediğimiz , referansın değeri değil, referansın değeri hakkındaki "gerçek" tir. Değerin olması (veya falsey) olmasını beklesek veya değerin typeof olmamasını beklesek bile, bir değer hakkındaki gerçeği bilmek isteyebileceğimiz bir kullanım durumu vardır .falseboolean


Uygulamada:

Dinamik yazarak (diğer adıyla "ördek yazarak") özellik işlevselliğini (ve bu durumda platform uyumluluğunu) algılayan özlü bir işlevi düşünün . trueBir kullanıcının tarayıcısı HTML5 <audio>öğesini destekliyorsa geri dönen bir işlev yazmak istiyoruz , ancak <audio>tanımlanmamışsa işlevin hata atmasını istemiyoruz ; ve try ... catcholası hataları işlemek için kullanmak istemiyoruz (çünkü bunlar brüttür); ve ayrıca işlevin içindeki özellik hakkındaki gerçeği tutarlı bir şekilde ortaya çıkarmayacak bir kontrol kullanmak istemiyoruz (örneğin, HTML5 desteklenmese bile document.createElement('audio')yine de adlı bir öğe oluşturacağız ).<audio><audio>


İşte üç yaklaşım:

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

Her fonksiyon a <tag>ve a için bir argüman kabul eder attribute, ancak her biri karşılaştırmaların belirlediğine göre farklı değerler döndürür.

Ama bekleyin, dahası var!

Bazılarınız muhtemelen bu özel örnekte, söz konusu nesnenin bir özelliğe sahip olup olmadığını kontrol etmek için biraz daha performanslı bir araç kullanarak bir özelliği kontrol edebileceğini fark ettiniz . Bunu yapmanın iki yolu vardır:

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

Konuya giriyoruz ...

Nadiren de olsa bu durumlar olabileceği gibi, trueboole olmayan, muhtemelen tanımsız bir değerden elde etmenin en kısa, en yüksek performans ve dolayısıyla en çok tercih edilen araçlarının kullanıldığı birkaç senaryo olabilir !!. Umarım bu gülünç bir şekilde temizler.


1
tamamen harika cevap, ama yarar göremiyorum !! yapı. Bir if()ifade zaten ifadeyi boole değerine çevirdiğinden, bir test işlevinin dönüş değerini boole değerine açıkça dönüştürmek gereksizdir - çünkü bir if()deyim yine de "doğruluk" === true . Yoksa gerçekten boolean olmak için doğru bir ifadeye İHTİYACINIZ olan bir senaryoyu kaçırıyor muyum true?
Tom Auger

1
@TomAuger if()ifadeleri, falsey değerlerine karşı boolean dökümü yapar, ancak bir nesneye aslında bir boolean bayrağı ayarlamak istediğinizi varsayalım - bunu bir if()ifadenin yaptığı gibi yayınlamaz . Örneğin , gerçek dönüş değeri yerine object.hasTheThing = !!castTheReturnValToBoolNoMatterWhat()ya trueda falseyerine getirilir. Başka bir örnek, belki de tüm yöneticilerin sahip idolduğu 0ve yönetici olmayanların id 1veya daha yüksek olmasıdır. trueBirisi yönetici değilse almak için yapabilirsiniz person.isNotAdmin = !!admin.id. Birkaç kullanım durumu, ancak olduğunda özlüdür.
Benny

103

!!sağındaki değeri eşdeğer boole değerine dönüştürür. (Zavallı adamın "tip döküm" tarzını düşünün). Onun niyeti kod umursamayan o okuyucuya aktarmaya genellikle neyi değer değişkeni olduğunu, ama onun neyi "gerçek" değer olduğunu.


4
Veya sağda bir boole değeri olması durumunda, hiçbir şey yapmaz.
Daniel A. White

3
@Daniel: !değeri hala sağa çevirir. Bir boolean durumunda, en sağdaki !değer değeri, en soldaki ise değeri bir !kez daha reddeder. Net etki, değişiklik olmamasıdır, ancak çoğu motor çift olumsuzlama için op kodları üretecektir.
Crescent Fresh

Ama amaç ne? if(0){...Javascript yaparsam zaten bunun yanlış olduğunu biliyorsa. Neden söylemek daha iyi if(!!0){...?
CodyBugstein

nokta içeriğini bilmediğiniz değişkenler içindir; bir tamsayı veya bir dize, bir nesne veya null, undefined, vb. olabilir. Varlığı test etmenin kolay bir yoludur.
mix3d

71

!!foounary değil operatörünü iki kez uygular ve +foosayıya atmak için unary artı kullanımına benzer bir boolean türüne dökmek için kullanılır ve boş bir dizeyi dizeye ''+foodökmek için birleştirir .

Bunun yerine bu kesmek, ayrıca (ilkel türlerine karşılık gelen yapıcı işlevleri kullanabilirsiniz olmadan kullanarak newaçıkça dökme değerlere, yani kadar)

Boolean(foo) === !!foo
Number(foo)  === +foo
String(foo)  === ''+foo

Ama sonra instanceof ile ilgili sorunlarla karşılaşabilirsiniz. yeni Boolean (1) instanceof Object -> true !! 1 instanceof Object -> false
Seamus

13
hayır, yapamazsınız: Oluşturucu işlevlerinin newcevabımda açıkça belirtildiği gibi çağrılmadığını
Christoph

2
fantastik! Bu, "0" olan dizeleri true yerine false olarak değerlendirmeniz gerektiğinde küçük bir saldırı için kullanışlıdır. (ör. seçimlerden değerleri okurken Dize olarak okundukları için). Bu nedenle, "0" değerini negatif (Boolean false) olarak değerlendirmek istiyorsanız, şunu yapın x="0": Number (veya + x) ile x=!!+x; //falseaynı olan, Boolean(Number(x))"0" dizesini 0'a dönüştürür, bu da DOES değerini false olarak değerlendirir ve sonra Boolean (!! x) doğrudan boole'ye çevirir. Çantada keklik!
DiegoDD

2
@DiegoDD neden seçsin !!+xvs x !== "0"?
placeybordeaux

@placeybordeaux, örneğin değeri başka bir şeyle karşılaştırıp karşılaştırmayacağınıza bakılmaksızın değeri dönüştürüp başka bir değişkene atamak isteyebilirsiniz.
DiegoDD

67

Birçok cevap işin yarısını yapıyor. Evet, !!X"X'in bir boolean olarak temsil edilen gerçeği" olarak okunabilir. Ancak !!, pratik olarak konuşursak, tek bir değişkenin doğru mu yoksa yanlış mı olduğunu anlamak için o kadar önemli değildir. !!myVar === truesadece aynı myVar. !!X"Gerçek" bir boole ile karşılaştırmak gerçekten yararlı değildir.

Hangi konuda kazanç !!birden değişkenlerin truthiness kontrol yeteneği birbirlerine karşı bir standardize, tekrarlanabilir (ve JSLint dostu) moda.

Basitçe döküm :(

Yani...

  • 0 === falseolduğunu false.
  • !!0 === falseolduğunu true.

Yukarıdakiler o kadar kullanışlı değil. if (!0)ile aynı sonuçları verir if (!!0 === false). Bir değişkeni boole'ye dönüştürmek ve sonra "gerçek" bir boole ile karşılaştırmak için iyi bir durum düşünemiyorum.

JSLint'in yönergelerinden "== ve! =" İfadesine bakın (not: Crockford sitesini biraz hareket ettiriyor; bu bağlantı bir noktada ölmekle yükümlüdür) neden biraz:

== ve! = Operatörleri karşılaştırma yapmadan önce baskı yaparlar. Bu kötüdür, çünkü '\ t \ r \ n' == 0 doğru olur. Bu tür hataları maskeleyebilir. JSLint == öğesinin doğru kullanılıp kullanılmadığını güvenilir bir şekilde belirleyemediğinden, == ve! = Kullanmamak ve bunun yerine her zaman daha güvenilir === ve! == işleçlerini kullanmak en iyisidir.

Yalnızca bir değerin gerçek veya sahte olduğunu düşünüyorsanız, kısa formu kullanın. Onun yerine
(foo != 0)

sadece söyle
(foo)

ve yerine
(foo == 0)

söyle
(!foo)

Not bazı olduğumuzu unintuitive vakalar bir boolean bir sayıya atılacaktır ( trueartığını 1ve falsekarşı 0birtakım etmek için bir boole karşılaştırırken). Bu durumda, !!zihinsel olarak yararlı olabilir. Yine de, bunlar, bir boolean olmayanı, sert tipli bir boole ile karşılaştırdığınız, imo, ciddi bir hatadır. if (-1)hala buraya gitmenin yolu.

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

Ve motorunuza bağlı olarak işler daha da delinir. Örneğin WScript ödülü kazanır.

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

Bazı tarihsel Windows jive nedeniyle , bu bir mesaj kutusuna -1 çıktı! Bir cmd.exe isteminde deneyin ve görün! Ancak WScript.echo(-1 == test())yine de size 0 veya WScript verir false. Gözlerini başka yöne çevirmek. İğrenç.

Doğruluk karşılaştırması :)

Peki ya eşit doğruluk / yanlışlık için kontrol etmem gereken iki değerim varsa?

Varmış gibi davran myVar1 = 0;ve myVar2 = undefined;.

  • myVar1 === myVar2açıktır 0 === undefinedve yanlıştır.
  • !!myVar1 === !!myVar2olduğu !!0 === !!undefinedve doğrudur! Aynı doğruluk! (Bu durumda, her ikisi de "bir sahtelik gerçeğine sahiptir".)

Yani gerçekten "boolean-cast değişkenleri" kullanmanız gereken tek yer, her iki değişkenin de aynı gerçekliğe sahip olup olmadığını kontrol ettiğiniz bir durum olsaydı, değil mi? Yani, kullanım !!iki vars olup olmadığını görmek için gerekirse truthy veya her ikisi falsy hem , (veya değil), eşit (veya değil) doğruluğuna .

Bunun için hazırlıksız, harika bir kullanım örneği düşünemiyorum. Belki bir formda "bağlantılı" alanlarınız var?

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

Demek artık ikisi için de bir truthy varsa veya eş adı ve yaşı ikisi için de bir falsy, devam edebilir. Aksi takdirde, yalnızca bir değere sahip bir alanınız (veya çok erken düzenlenmiş bir evlilik) vardır ve errorObjectskoleksiyonunuzda fazladan bir hata oluşturmanız gerekir .


EDIT 24 Eki 2017, 6 Şub 19:

Açık Boole değerleri bekleyen 3. taraf kütüphaneler

İşte ilginç bir durum ... !!3. taraf kütüphaneleri açık Boole değerleri beklediğinde yararlı olabilir.

Örneğin, JSX'teki False (React), basit sahtecilikle tetiklenmeyen özel bir anlama sahiptir. JSX'inizde aşağıdaki gibi bir şey döndürmeyi denediyseniz, bir int bekliyoruz messageCount...

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

... 0sıfır mesajınız olduğunda React'in oluşturulmasını gördüğünüzde şaşırabilirsiniz . JSX'in görüntülenmemesi için açıkça false döndürmeniz gerekir. Yukarıdaki ifade 0, JSX'in gerektiği gibi oluşturduğu döndürür . Sahip olmadığınızı söyleyemez Count: {messageCount && <div>Get your count to zero!</div>}(ya da daha az çelişkili bir şey).

  • Bir düzeltme coerces BangBang, içerir 0içine !!0olan false:
    {!!messageCount && <div>You have messages!</div>}

  • JSX dokümanları, daha açık olmanızı, kendi yorum kodunuzu yazmanızı ve bir Boole için zorlamak üzere bir karşılaştırma kullanmanızı önerir.
    {messageCount > 0 && <div>You have messages!</div>}

  • Üçlü ile kendimde daha rahat davranıyorum -
    {messageCount ? <div>You have messages!</div> : false}

Typescript'te aynı anlaşma: Bir boole döndüren bir fonksiyonunuz varsa (veya bir boolean değişkenine değer atarsanız), [genellikle] bir boolean-y değeri döndüremez / atayamazsınız; kuvvetle yazılmış bir boole olmalıdır. Bu, iff'nin myObjectgüçlü bir şekilde yazıldığı , return !myObject;bir boole döndüren bir işlev için çalıştığı, ancak return myObject;olmadığı anlamına gelir. Sen zorunda return !!myObjecttypescript beklentilerini eşleşecek.

Patlama için istisna? Eğer myObjectbir oldu any, geri JavaScript'in Vahşi Batı'da konum ve olmadan iade edebilirsiniz !!dönüş tipi bir boolean olsa bile.

Bunların JavaScript'e özgü olmayan JSX ve Dizgi metinleri kuralları olduğunu unutmayın .

Ancak 0, işlenmiş JSX'inizde garip s görürseniz, gevşek falsy yönetimini düşünün.


İyi açıklama. Yani söyleyebilirim! Bu Çalışan özellik algılama örneğinde kesinlikle gerekli değildir ? if (!!window.Worker)
jk7

2
Hayır, buna ihtiyacın olmayacaktı. Doğruluk ve true"dışsal" olarak tamamen aynı şekilde çalışır if. Denemeye devam ediyorum, ancak değeri daha sonra tekrar kullanırsanız okunabilirlik haricinde, qkütüphane örneğinde olduğu gibi, kıvrımlı "doğrulukları karşılaştır" durumu dışında, bir doğruluk değerini bir boole değerine dökmeyi tercih etmek için bir neden düşünemiyorum. . Ama o zaman bile, bu bilgi kaybı olan bir kısayoldur ve her seferinde gerçeği değerlendirmek için daha iyi olduğunuzu iddia ediyorum.
15'te

Tepki, kullanmaya başladığımız ana nedendir !! ama çok rahat ve tekrarlanabilir bir şey oluyor. Altta yatan tipin ne olduğu hakkında değil, sadece bir şeyin gerçekliği veya yanlışlığı hakkında endişelenmem gerekiyor.

Yorumsuz downvotes endişenizi gidermeyi zorlaştırıyor! Neyin kötü göründüğünü bilmeme izin ver, ben de buna değinmekten mutlu olurum.
ruffin

55

Sadece mantıksal DEĞİL operatörü, iki kez - bir şeyi boole'ye dönüştürmek için kullanılır, örneğin:

true === !!10

false === !!0

3
Bunu neden dünyada yapasın ki? Kullan ! operatör boolean dönüştürmek sonra tür karşılaştırmak için === kullanın? Sadece tür güvenliğiniz olmadığını kabul edin ve val> 0 ya da başka bir şey yapın.
Darren Clark

43
@Darren: Türleri karşılaştırmıyor; cevabında iddialar yazarak size sonuçların ne olduğunu anlatıyor.
Yörüngedeki Hafiflik Yarışları


26

Çift notoperasyon. Birincisi !, değeri boole değerine dönüştürür ve mantıksal değerini tersine çevirir. İkincisi !mantıksal değeri tersine çevirir.


26

!!Operatörün çifte olumsuzlama ile sonuçlandığı anlaşılıyor .

var foo = "Hello World!";

!foo // Result: false
!!foo // Result: true

23

Boolean()Döküm işlevinin davranışını simüle eder . Birincisi, NOThangi işlenen verilirse verilsin bir Boolean değeri döndürür. İkincisi NOTbu Booleandeğeri reddeder ve böylece truebir değişkenin Boole değerini verir . Sonuç, Boolean()işlevi bir değer üzerinde kullanmakla aynıdır .


20

! "boolean not", temel olarak boolean karşısına "enable" değerini belirtir. İkinci ! bu değeri çevirir. Yani, !!enable"etkin değil" anlamına gelir, size enablebir boole değeri verir .


18

Bahsetmeye değer olduğunu düşünüyorum, mantıksal VE / VEYA ile birleştirilmiş bir durum bir boole değeri döndürmez ama && ve ilk başarı durumunda ilk başarısız veya ilk başarısız || durum zincirinin.

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

Durumu gerçek bir boole değişmezine dönüştürmek için çifte olumsuzlamayı kullanabiliriz:

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

17

!!o kullanıyor NOT, iki kez birlikte çalışmasını !bir değer dönüştürmek booleanburada nasıl çalıştığını görmek için basit bir örnek, bunu ve ters !!işler:

İlk başta, sahip olduğunuz yer:

var zero = 0;

Sonra !0, boolean dönüştürülecek ve olarak değerlendirilecektir true, çünkü 0 falsy, böylece ters değer elde edersiniz ve boole dönüştürülür, böylece değerlendirilir true.

!zero; //true

ancak değerin ters boole sürümünü istemiyoruz , bu nedenle sonucumuzu almak için tekrar tersine çevirebiliriz! Bu yüzden başka bir tane kullanıyoruz !.

Temel olarak, !!emin olun, elde ettiğimiz değer boolean, falsy, doğruluk veya dize vb.

BooleanJavascript işlevini kullanmak gibidir , ancak bir değeri boole'ye dönüştürmenin kolay ve kısa yolu:

var zero = 0;
!!zero; //false

15

!!Yapı kendi Boole eşdeğer içine herhangi bir JavaScript ifadesini dönüm basit bir yoludur.

Örneğin: !!"he shot me down" === trueve !!0 === false.


2
Önemli ayrımı çok yakın. Anahtar 0 === falseyanlış ve !!0 === falsegerçek olmasıdır.
ruffin

14

Tek bir operatör değil, iki. Aşağıdakine eşdeğerdir ve boole değerine değer atmanın hızlı bir yoludur.

val.enabled = !(!enable);

10

Bu insanların geçersiz kılma C ++ bir artık olduğunu sanıyorum! operatörü değil, bool operatörünü değil.

Bu durumda olumsuz (veya olumlu) bir cevap almak için önce! operatör bir boolean almak için, ancak olumlu durumda kontrol etmek istiyorsanız kullanmak istiyorsunuz !!.


10

ifVe whiletablolar ve ?operatör kullanımı gerçeği değerleri vadede kod hangi dalı belirlemek için. Örneğin, sıfır ve NaN sayıları ve boş dize yanlıştır, ancak diğer sayılar ve dizeler doğrudur. Nesneler doğrudur, ancak tanımsız değerdir ve nullikisi de yanlıştır.

Çift olumsuzlama operatörü !!bir değerin gerçek değerini hesaplar. Aslında iki operatörün olduğu !!xanlamına gelir !(!x)ve aşağıdaki gibi davranır:

  • Eğer x, yanlış bir değerdir !xolduğunu trueve !!xbir false.
  • Eğer xgerçek bir değer !xise false, !!xve'dir true.

Boolean bağlamda üst düzeyinde kullanıldığında ( if, whileya da ?), !!operatör davranışsal no-operasyon. Örneğin, if (x)ve if (!!x)aynı anlama geliyor.

Pratik kullanımlar

Bununla birlikte, birkaç pratik kullanımı vardır.

Bir kullanım, bir nesneyi gerçek değerine kayıtsız olarak sıkıştırmaktır, böylece kodunuz büyük bir nesneye başvuruda bulunmaz ve onu canlı tutar. Çöp toplayıcı !!some_big_objectiçin bir değişkene atama some_big_objectyapalım. Bu, bir nesne ya da gibi yanlış bir değer nullya da tarayıcı özelliği algılama gibi tanımsız değer üreten durumlar için kullanışlıdır .

C'nin ilgili !!operatörü hakkında bir cevapta bahsettiğim başka bir kullanım, yaygın yazım hataları ve baskı tanılama arayan "tüy bırakmayan" araçlardır. Örneğin, hem C hem de JavaScript'te, Boole işlemleri için birkaç yaygın yazım hatası, çıktısı Boole gibi olmayan başka davranışlar üretir:

  • if (a = b)atamanın ardından gerçeğin değerinin kullanılması b; if (a == b)eşitlik karşılaştırmasıdır.
  • if (a & b)bir bitsel VE; if (a && b)mantıklı bir VE. 2 & 5olduğu 0(yanlış bir değer); 2 && 5doğru.

!!Operatör ne yazmış ne anlama geldiğini olduğu tiftik aracını güvence: bu işlem, daha sonra sonucun doğruluk değerini almak yoktur.

Üçüncü kullanım mantıksal XOR ve mantıksal XNOR üretmektir. Hem C hem de JavaScript'te, a && bmantıksal bir AND (her iki taraf doğruysa true) a & bgerçekleştirir ve bitsel VE gerçekleştirir. a || bmantıksal bir OR gerçekleştirir (en az biri doğruysa true) ve a | bbit şeklinde VEYA gerçekleştirir. Bitsel bir XOR (özel OR) a ^ bvar, ancak mantıksal XOR için yerleşik bir operatör yok (tam olarak bir taraf doğruysa true). Örneğin, kullanıcının tam olarak iki alandan birine metin girmesine izin vermek isteyebilirsiniz. Ne yapabilirsiniz bir hakikat değerine her dönüştürmek ve bunları karşılaştırmak olduğunu: !!x !== !!y.


8

Çift boole negatiflemesi. Genellikle değerin tanımlanıp tanımlanmadığını kontrol etmek için kullanılır.


8

Burada çok sayıda harika yanıt var, ancak bu kadar aşağı okuduysanız, bu benim 'anlamama' yardımcı oldu. Konsolu Chrome'da (vb.) Açın ve yazmaya başlayın:

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

Doğal olarak, bunların hepsi sadece yazmakla aynıdır !! someThing, ancak eklenen parantezler daha anlaşılır olmasına yardımcı olabilir.


8

!!x için kestirme Boolean(x)

İlk patlama js motorunu çalıştırmaya zorlar, Boolean(x)ancak değeri ters çevirme yan etkisine de sahiptir. Böylece ikinci patlama yan etkiyi geri alır.


8

Her şeyi boole yapmaya zorlar.

Örneğin:

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

7

Bu soru oldukça kapsamlı bir şekilde cevaplandı, ancak umarım olabildiğince basitleştirilmiş, anlamını veren bir cevap eklemek istiyorum! kavramak kadar basit.

Javascript "doğruluk" ve "falsey" değerlerine sahip olduğu için, incelenen değer veya ifade aslında trueveya olmasa da, diğer ifadelerde değerlendirildiğinde doğru veya yanlış bir duruma neden olacak ifadeler vardır false.

Örneğin:

if (document.getElementById('myElement')) {
    // code block
}

Bu öğe aslında mevcutsa, ifade true olarak değerlendirilir ve kod bloğu yürütülür.

Ancak:

if (document.getElementById('myElement') == true) {
    // code block
}

... gerçek bir koşula neden OLMAZ ve eleman mevcut olsa bile kod bloğu yürütülmez.

Neden? Çünkü document.getElementById()bu if()ifadede doğru olarak değerlendirilecek bir "doğruluk" ifadesidir , ancak bunun gerçek bir boole değeri değildir true.

Bu durumda çift "değil" oldukça basittir. Sadece notarka arkaya iki s.

Birincisi, gerçek veya mantıksal bir değerle sonuçlanan doğruluk veya falsey değerini basitçe "tersine çevirir" ve daha sonra ikincisi, gerçek durumuna geri döndürür, ancak şimdi gerçek bir boole değerinde. Bu şekilde tutarlılığınız olur:

if (!!document.getElementById('myElement')) {}

ve

if (!!document.getElementById('myElement') == true) {}

İKİ beklendiği gibi doğru dönecektir.


7

Sadece eklemek istedim

if(variableThing){
  // do something
}

aynıdır

if(!!variableThing){
  // do something
}

Ancak, bir şey tanımlanmadığında bu bir sorun olabilir.

// a === undefined, b is an empty object (eg. b.asdf === undefined)
var a, b = {};

// Both of these give error a.foo is not defined etc.
// you'd see the same behavior for !!a.foo and !!b.foo.bar

a.foo 
b.foo.bar

// This works -- these return undefined

a && a.foo
b.foo && b.foo.bar
b && b.foo && b.foo.bar

Buradaki hile, &&s zincirinin bulduğu ilk falsey değerini döndürecektir - ve bu bir if ifadesine vb. Beslenebilir. Yani b.foo tanımsızsa, tanımsız olarak dönecek ve b.foo.barifadeyi atlayacaktır ve hata.

Yukarıdaki tanım tanımsız, ancak boş bir dizeniz varsa, false, null, 0, undefined bu değerler geri döner ve zincirde karşılaştığımız anda - []ve {}her ikisi de "doğrudur" ve sözde " && chain "seçeneğini seçin.

PS Aynı şeyi yapmanın başka bir yolu, (b || {}).fooeğer b tanımsızsa o zaman b || {}olur {}ve "tanımsız" içindeki bir değere erişmeye çalışmak yerine boş bir nesnede (hata yok) bir değere erişirsiniz (hataya neden olur) ). Yani, (b || {}).fooaynıdır b && b.foove ((b || {}).foo || {}).baraynı b && b.foo && b.foo.bar.


iyi bir nokta - cevabımı değiştirdim. Bir nesnede sadece üç seviye derinlikte iç içe geçtiği zaman olur, çünkü dediğiniz gibi ({}).anythingvereceksinizundefined
Ryan Taylor

5

Tüm bu harika cevapları gördükten sonra, kullanmak için başka bir neden eklemek istiyorum !!. Şu anda Açısal 2-4'te (TypeScript) çalışıyorum ve falsekullanıcımın kimliği doğrulanmadığında olduğu gibi bir boole döndürmek istiyorum . Eğer kimliği doğrulanmamışsa, jeton dizesi nullveya olur "". Sonraki kod bloğunu kullanarak bunu yapabilirsiniz:

public isAuthenticated(): boolean {
   return !!this.getToken();
}

4

İşte açısal js bir kod parçası

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

 var rafSupported = !!requestAnimationFrame;

amaçları rafSupported öğesini, istekte işlevin kullanılabilirliğine bağlı olarak true veya false olarak ayarlamaktır.

genel olarak aşağıdaki şekilde kontrol edilerek elde edilebilir:

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

kısa yol kullanıyor olabilir!

rafSupported = !!requestAnimationFrame ;

yani requestAnimationFrame bir işlev atandıysa! requestAnimationFrame yanlış ve bir tane daha olur! doğru olur

requestAnimationFrame tanımsız olarak değerlendirilirse, requestAnimationFrame doğru ve bir tane daha olur! yanlış olur


3

JavaScript'teki bazı işleçler örtük tür dönüşümleri gerçekleştirir ve bazen tür dönüşümü için kullanılır.

Tekli !operatör, işlenenini bir boole'ye dönüştürür ve reddeder.

Bu gerçek, kaynak kodunuzda görebileceğiniz aşağıdaki deyime yol açar:

!!x // Same as Boolean(x). Note double exclamation mark

3

Mantıksal değil, iki kez işleci kullanın
! True = false
ve !! true = true


3

Bir değişkenin boole değerini döndürür.

Bunun yerine Booleansınıf kullanılabilir.

(lütfen kod açıklamalarını okuyun)

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`

Yani, Boolean(X) = !!Xkullanımda.

Lütfen kod snippet'ini aşağıdan kontrol edin

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.