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


Tanımadığım bir operatörün kullandığı bazı kodları, iki ünlem işareti şeklinde gördüm: !!. 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;

2330
2018-04-24 08:13


Menşei


Bunu "bang, bang boolean" ile hatırla - Gus
Sadece kayıt için, orada alıntı yapılan şeyi yapmayın. Yap if(vertical !== undefined) this.vertical = Boolean(vertical); - ne olup bittiği çok daha temiz ve daha nettir, gereksiz bir ödev gerektirmez, tamamen standarttır ve aynı derecede hızlıdır (mevcut FF ve Chrome'da) jsperf.com/boolean-conversion-speed . - Phil H
!! operatör değildir. Bu sadece! operatör iki kez. - Vivek
Sadece kayıt için, Boolean(5/0) ile aynı değil !!5/0 - schabluk
@schabluk, kayıt için operasyonların sırası sebebi !!5/0 üretir Infinity ziyade truetarafından üretildiği gibi Boolean(5/0). !!5/0 eşdeğerdir (!!5)/0 -- diğer adıyla true/0 - nedeniyle ! operatör daha yüksek bir önceliğe sahip / Şebeke. Booleanize etmek istiyorsan 5/0 bir çift patlama kullanarak, kullanmanız gerekir !!(5/0). - matty


Cevaplar:


coerces oObject boole için. Eğer falsey olsaydı (ör. 0, null, undefined, vb) olacak false, aksi takdirde, true.

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

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

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

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

Eğer sen

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

ama eğer sen ⇒

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

2076
2018-04-24 08:18



Bir nonbooleanı tersine çevrilmiş bir boole'ye dönüştürür (örneğin, 5, false olur, çünkü 5, JS'de yanlış olmayan bir değerdir), sonra boolean-dönüştürür, böylece orijinal değeri bir boole (yani !! 5 olur) Gerçek olmak). - Chuck
Bunu tanımlamanın kolay bir yolu: Boole (5) === !! 5; Aynı döküm, daha az karakter. - Micah Snyder
Bu, gerçek değerleri boolean true değerine dönüştürmek için kullanılır ve falsi değerleri de çok yanlıştır. - thetoolman
@Micah Snyder, JavaScript'te boole'ları yeni Boolean () ile kutlayan 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
Bildiğim kadarıyla, bu bang-bang paterni, eğer (… _ ifadesi) içinde sadece bir boolean döndüren bir fonksiyonun dönüş ifadesinde yararlı değildir. - rds


Bir tür dönüşüm yapmak için korkunç bir yoldur.

! olduğu DEĞİL. Yani !true olduğu false, ve !false olduğu true. !0 olduğu true, ve !1 olduğu false.

Yani bir değeri bir boole dönüştürüyorsunuz, sonra onu tersine çevirip tekrar ters çeviriyorsunuz.

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

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

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

733
2017-09-10 17:28



!! false = false. !! true = true - roosteronacid
(userId == 0) ? false : true; Beynimi en az acıtır. - Andy Gaskell
Korkunç belirsiz .... güzel gözümde özlü .... - James Westgate
"Anlamak daha kolay" varyantı burada anlamak gerçekten çok daha kolay mı? 0'a karşı kontrol 0'a karşı gerçek bir kontrol değildir, fakat Javascript'in 0'a eşit olduğunu düşündüğü değerlerin biraz garip listesiyle ilgili bir kontrol. userId ? true : false  dönüşümün devam ettiğini ve userId değerinin açıkça ayarlanmış olduğu durumu ele aldığının daha net anlaşılmasını sağlar. undefined - Ben Regenspan
Beynimin kod çözme sorunu yok !!var içine Boolean(var) .. ve !! Daha hızlıdır (daha az işlem) ve alternatiflerden daha kısadır. - adamJLev


!!expr bir Boole değeri döndürür (true veya false) bağlı olarak truthiness ifadenin Boole olmayan türlerde kullanıldığında daha anlamlı olur. Bu örnekleri, özellikle 3. örneği ve ileriyi 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!

376
2018-05-15 09:06



Dikkat değer: !!new Boolean(false) // true - Camilo Martin
...Ayrıca !!Boolean(false) // false - Camilo Martin
new Boolean(false) bir nesnedir ve bir falsi değeri içeriyor olsa bile bir nesne doğrudur! - Salman A
Evet biliyorum, ama çoğu yerli kurucu (String, Number, Datevb) işlevler olarak da çağrılabilir olması gerekir, ancak bu durumda sonuç farklıdır! - Camilo Martin
@SalmanA Ayrıca javascript'in mantıklı olduğunu da umarım: D - Camilo Martin


Biraz çay demeye:

!! operatör değildir. Bu çift kullanım ! - mantıksal "değil" operatörü.


Teoride:

! Bir değerin ne olmadığını “doğruluk” u belirler:

  • Gerçek şu ki false değil true (bu yüzden !false Sonuçlar içinde true)

  • Gerçek şu ki true değil false (bu yüzden !true Sonuçlar içinde false)


!! bir değerin ne olduğunu "doğruyu" belirler değil değil:

  • Gerçek şu ki true değil değil  true (bu yüzden !!true sonuç true)

  • Gerçek şu ki false değil değil  false (bu yüzden !!false sonuç false)


Karşılaştırmada tespit etmek istediğimiz şey "gerçek" dir. hakkında referansın değeri değil değeri referansın kendisi. Değerin olmasını beklese bile, bir değer hakkındaki gerçeği bilmek isteyebileceğimiz bir kullanım vakası var. false (ya da falsey), ya da değerin boolean.


Uygulamada:

Özellik işlevselliğini (ve bu durumda platform uyumluluğunu) algılayan kısa bir işlev düşünün. dinamik yazım (aka "ördek yazarak"). Geri dönen bir işlev yazmak istiyoruz true Bir kullanıcının tarayıcısı HTML5'i destekliyorsa <audio> öğeyi, ancak işlevini bir hata atmak istemiyoruz <audio> undefined; ve kullanmak istemiyoruz try ... catch olası hataları işlemek için (çünkü onlar brüt); ve ayrıca Bu özellik ile ilgili gerçekleri tutarlı bir şekilde ortaya çıkarmayacak bir işlev içinde kontrol kullanmak istemiyoruz (örneğin, document.createElement('audio') yine de bir eleman oluşturacak <audio> HTML5 olsa bile <audio> desteklenmiyor).


İş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 işlev, bir <tag> ve bir attribute aramak için, ancak her biri karşılaştırmaların ne belirlediğine göre farklı değerler döndürür.

Ama bekle, dahası var!

Bazılarınız muhtemelen bu özel örnekte, birazcık kullanarak bir mülkün kontrol edilebileceğini fark etmişsinizdir. daha fazla performans söz konusu nesnenin olup olmadığını kontrol etmek vardır bir özellik. 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

Digress ...

Bununla birlikte, bu durumların nadir görülmesi, en özlü, en verimli ve en çok tercih edilen araçların elde edildiği birkaç senaryo olabilir. true boolean olmayan, muhtemelen tanımsız bir değerden gerçekten kullanılarak !!. Umarım bu saçma bir şekilde temizler.


130
2018-02-22 23:45



Tamamen müthiş bir cevap, ama yardımcı programını göremiyorum !! yapı. Bir yana if() ifadesi, boolean için ifadeyi kullanır, boole için bir sınama işlevinin dönüş değerini açıkça belirtmek gereksizdir - çünkü "doğruluk" === true if() ifade yine de gider. Ya da aslında boolean için doğru bir ifadeye ihtiyaç duymadığınız bir senaryoyu kaçırıyor muyum? true? - Tom Auger
@TomAuger if() ifadeler, falsey değerlerine karşı boolean yapar, ancak bir nesne üzerinde aslında bir boole bayrağı koymak istediğinizi söyler. if() ifade yapar. Örneğin object.hasTheThing = !!castTheReturnValToBoolNoMatterWhat() ya ayarlayabilir true veya false gerçek dönüş değeri yerine. Başka bir örnek belki de tüm yöneticiler id arasında 0 ve yönetici olmayanlar id 1 veya daha yüksek. Almak trueEğer birisi yönetici değilse person.isNotAdmin = !!admin.id. Birkaç kullanım durumu var, ancak var olduğunda özlü. - Benny Schmidt


!! değeri, karşılık gelen boole değerine sağa dönüştürür. (Zavallı adamın "tip-döküm" şeklini düşünün). Onun niyet genellikle okuyucuya kodun umursamadığı ne değer değişkendir, ama ne "gerçek değer olduğunu.


87
2017-09-10 17:26



Ya da sağdaki bir boole değeri durumunda, hiçbir şey yapmaz. - Daniel A. White
@Daniel: ! hala değeri sağa çevirir. Bir boolean durumunda en sağdaki ! en sol iken değeri reddeder ! bir kez daha reddeder. Net etki, herhangi bir değişiklik olmamasıdır, ancak çoğu motor çift olumsuzluk için op kodları üretecektir. - Crescent Fresh
Ama mesele nedir? Eğer yaparsam if(0){... Javascript zaten bunun yanlış olduğunu biliyor. Neden söylemek daha iyidir if(!!0){...? - CodyBugstein
Buradaki nokta, içeriğini bilmediğiniz değişkenler içindir; bir tamsayı veya bir dize, bir nesne veya boş, tanımsız, vb. olabilirse. Bu, varlığı test etmenin kolay bir yoludur. - mix3d


!!foo unary operatörünü iki kez uygular ve unary plus kullanımına benzer boole türüne yayın yapmak için kullanılır +foo sayıya dökmek ve boş bir dizeyi birleştirmek ''+foo dizgiye yayınlamak için

Bu hackler yerine, ilkel türlere karşılık gelen yapıcı işlevlerini de kullanabilirsiniz (olmadan kullanma new) açık bir şekilde döküm değerleri

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

59
2017-09-10 21:15



Ama sonra instanceof ile sorunlara koşabilirsin. new Boolean (1) instanceof Object -> true !! 1 instanceof Nesne -> yanlış - Seamus
hayır, yapamazsınız: yapıcı işlevlerin çağrılmadan çağrıldığını new - cevabımda açıkça belirtildiği gibi - Christoph
fantastik! Bu, "0" ile dizeleri true yerine false olarak değerlendirmeniz gerektiğinde küçük bir kesmek için kullanışlıdır. (diğer bir deyişle, değerleri okunduğunda, çünkü bunlar String olarak okunur). Yani, "0" ı negatif olarak düşünmek istiyorsanız (Boolean false) x="0" sadece yap: x=!!+x; //false aynı olan Boolean(Number(x)) Sayı (veya + x), "0" dizesini 0'a dönüştürür, bu da false değerini değerlendirir ve sonra Boole (!! x) doğrudan booleanı çevirir. Tereyağından kıl çeker gibi! - DiegoDD
@DiegoDD neden tercih ederdiniz? !!+x vs x !== "0"? - placeybordeaux
@placeybordeaux Örneğin, değeri başka bir şeye benzetip karşılaştırmayacağınıza bakılmaksızın değeri dönüştürmek ve diğer değişkene atamak isteyebilirsiniz. - DiegoDD


Pek çok cevap işin yarısını yapıyor. Evet, !!X “X'in gerçekliği” [boolean olarak temsil edilir] ”olarak okunabilir. Fakat !! pratik olarak konuşmadığı için, tek bir değişkenin (ya da birçok değişken olsa bile) doğru ya da yanlış olduğunu anlamak için çok önemlidir. !!myVar === true sadece aynı myVar. karşılaştırma !!X "gerçek" bir boole için gerçekten yararlı değildir.

Ne kazanıyorsun? !! çoklu değişkenlerin doğruluğunu kontrol etme becerisidir. birbirlerine karşı Tekrarlanabilir, standartlaştırılmış (ve JSLint dostu) bir moda.

Sadece döküm :(

Yani...

  • 0 === false olduğu false.
  • !!0 === false olduğu true.

Yukarıdakiler çok kullanışlı değil. if (!0) ile aynı sonuçları verir if (!!0 === false). Bir değişkeni boolean'a dökmek için iyi bir durum düşünemiyorum ve daha sonra "gerçek" bir boolean ile karşılaştırabiliyorum.

Bkz. "== ve! =" JSLint'in talimatları (Not: Crockford siteyi biraz ilerletiyor; bu noktada bir noktada ölmekle yükümlüdür) nedenini biraz:

== ve! = Operatörler karşılaştırmadan önce baskı yaparlar. Bu kötü çünkü '\ t \ r \ n' == 0 'un doğru olmasına neden oluyor. Bu, tür hatalarını maskeleyebilir. JSLint, == doğru kullanıldığında güvenilir bir şekilde belirlenemiyor, bu yüzden == ve! = Kullanmamak ve her zaman daha güvenilir === ve! == işleçlerini kullanmak en iyisidir.

Bir değerin yalnızca doğru ya da yanlış olduğunu düşünüyorsanız, kısa formu kullanın. Yerine
(foo != 0)

sadece söyle
(foo)

ve yerine
(foo == 0)

söylemek
(!foo)

Bazı var ki beklenmedik durumlar bir boole bir sayıya dökülecek (true için yayınlanıyor 1 ve false için 0bir booleanı bir sayı ile karşılaştırırken. Bu durumda, !! Zihinsel olarak yararlı olabilir. Yine de, bunlar, boolean olmayanları, sabit yazılan bir boolean ile karşılaştırdığınızı gösterir, yani, imo, ciddi bir hatadır.  if (-1) hala buraya gitmek için yoldur.

╔═══════════════════════════════════════╦═══════════════════╦═══════════╗
║               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 her şey motorunuza bağlı olarak daha da çılgınlaşıyor. WScript, örneğin, ödülü kazanır.

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

Nedeniyle bazı tarihi Windows jive, bir mesaj kutusuna -1 çıktı! Bir cmd.exe komut isteminde deneyin ve görün! Fakat WScript.echo(-1 == test()) hala 0 veya WScript kullanıyor false. Gözlerini başka yöne çevirmek. Çok iğrenç.

Karşılaştırma gerçeği :)

Ama ya iki değere sahip olursam, eşit doğrulukları / bilmeceleri kontrol etmem gerekiyor?

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

  • myVar1 === myVar2 olduğu 0 === undefined ve açıkça yanlıştır.
  • !!myVar1 === !!myVar2 olduğu !!0 === !!undefined ve doğrudur! Aynı gerçek! (Bu durumda, her ikisi de "falsi bir doğruluk var".)

Yani "boole cast değişkenlerini" kullanmanız gereken tek yer, eğer her iki değişkenin de olup olmadığını kontrol ettiğiniz bir durumunuz olsaydı olurdu. aynı doğruluk, değil mi? Yani, kullanım !! iki vars olup olmadığını görmek gerekirse hem gerçek hem de felç (ya da değil), yani eşit (ya da değil) truthiness.

Bu offhand için büyük, gayri meşru bir kullanım vakası düşünemiyorum. Belki bir formda "bağlantılı" alanlar 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.";
}

Yani şimdi ikiniz için bir gerçek varsa veya hem eş ismi hem de yaş için bir falsi, devam edebilirsiniz. Aksi takdirde, bir değeri (ya da çok erken düzenlenmiş bir evlilik) olan sadece bir alanınız vardır ve ek bir hata yaratmanız gerekir. errorObjects Toplamak.


24 Ekim 2017’de DÜZENLEME: 

Açık Boolean değerleri bekleyen 3. taraf kitaplıkları

İşte ilginç bir vaka ... !! Üçüncü taraf lib'lar, açık Boole değerlerini beklediklerinde yararlı olabilir.

Örneğin, JSX'de yanlış (React) özel bir anlama sahiptir Bu basit sahteliği tetiklemiyor. JSX'inizde aşağıdaki gibi bir şey döndürmeyi denediyseniz, int messageCount...

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

... React render a şovunu görmekten şaşırabilirsiniz. 0 sıfır mesajınız olduğunda. Oluşturmak için JSX için açıkça false döndürmeniz gerekir. Yukarıdaki beyannameyi döndürür 0JSX, gerektiği gibi mutlu bir şekilde işler. Sana sahip olmadığını söyleyemem Count: {messageCount && <div>Get your count to zero!</div>} (ya da daha az bir şey).

  • Bir düzeltme, patlayan bangbang'ı içeriyor 0 içine !!0, hangisi false:
    {!!messageCount && <div>You have messages!</div>}

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

  • Ben kendimi bir üçlüsle kendimden çekişme konusunda daha rahatım -
    {messageCount ? <div>You have messages!</div> : false}

Unutmayın ki bu bir JSX sözleşmesidir, JavaScript'in doğasında olmayan.

Ama garip görüyorsanız 0işlenen JSX'inizde, gevşek yönetim yönetimini düşünün.


47
2018-04-29 18:14



İyi açıklama. Yani söyler misin? bu kesinlikle gerekli değildir İşçi özelliği algılama örnek? if (!!window.Worker) - jk7
Hayır, buna ihtiyacınız olmaz. Hakikat ve true "harici olarak" tam olarak aynı şekilde çalışır if. Denemeye devam ediyorum, ancak değeri daha sonra yeniden kullanmanız durumunda okunabilirlik dışında, yukarıda anlatılan "karşılaştırmalı gerçekleri karşılaştır" durumunun dışındaki bir "boolean" değerine "boolean" değerine dönüştürmek için bir neden düşünemiyorum. q kütüphane örneği. Ama o zaman bile, bu bilgi kayıplı bir kısayol, ve her seferinde doğruyu değerlendirmekten daha iyi olduğunuzu iddia ediyorum. - ruffin
React kullanmaya başladığımız ana nedeni! desen, ama çok uygun ve tekrarlanabilir bir şey olur. Sadece bir şeyin doğruluğu ya da ahlaksızlığı, altta yatan türün ne olduğu konusunda endişelenmem gerekiyor. - Alexander Pritchard


Sadece mantıksal NOT operatörü, iki kere - bir şeyi boole dönüştürmek için kullanılır, ör .:

true === !!10

false === !!0

44
2018-04-24 08:18



Neden yeryüzünde yaparsın? Kullan ! operatör boole dönüştürmek sonra === türü karşılaştırmak için? Sadece güvenliğiniz olmadığını ve> 0 veya bir şey yaptığınızı kabul edin. - Darren Clark
@Darren: O, türleri karşılaştırmıyor; Cevabındaki iddiaları yazarak sonuçların ne olduğunu size anlatıyor. - Lightness Races in Orbit