क्या है !! (नहीं) जावास्क्रिप्ट में ऑपरेटर?


3103

मैंने कुछ कोड को देखा जो एक ऑपरेटर का उपयोग करने के लिए लगता है जिसे मैं नहीं पहचानता, दो विस्मयादिबोधक बिंदुओं के रूप में, जैसे !!:। क्या कोई मुझे बता सकता है कि यह ऑपरेटर क्या करता है?

जिस संदर्भ में मैंने यह देखा वह था,

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

944
इसे याद रखें "बैंग, बैंग यू बूलीयन"
गूस

75
बस रिकॉर्ड के लिए, वहाँ क्या उद्धृत नहीं है। करो if(vertical !== undefined) this.vertical = Boolean(vertical);- यह बहुत साफ और स्पष्ट है कि क्या चल रहा है, किसी अनावश्यक असाइनमेंट की आवश्यकता नहीं है, पूरी तरह से मानक है, और बस के रूप में तेजी से (वर्तमान एफएफ और क्रोम पर) jsperf.com/boolean-conversion-speed है
फिल एच

73
!! संचालक नहीं है। यह सिर्फ है! ऑपरेटर दो बार।
विवेक

11
सिर्फ रिकॉर्ड के लिए, Boolean(5/0)वही नहीं है!!5/0
schabluk

63
@schabluk, रिकार्ड के लिए, आपरेशन के आदेश कारण है !!5/0का उत्पादन Infinityकरने के बजाय true, के रूप में द्वारा उत्पादित Boolean(5/0)!!5/0के बराबर है (!!5)/0- उर्फ true/0- !ऑपरेटर के मुकाबले /ऑपरेटर की उच्च प्राथमिकता होने के कारण । यदि आप 5/0डबल-बैंग का उपयोग करके बूलियन करना चाहते हैं , तो आपको उपयोग करने की आवश्यकता होगी !!(5/0)
मैटी

जवाबों:


2743

को परिवर्तित Objectकरता है boolean। यदि यह falsey था (जैसे 0, null, undefined, आदि), यह हो जाएगा false, अन्यथा, true

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

तो !!एक ऑपरेटर नहीं है, यह सिर्फ !दो बार ऑपरेटर है।

वास्तविक विश्व उदाहरण "टेस्ट IE संस्करण":

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

अगर आप ⇒

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

लेकिन अगर आप ⇒

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

123
यह एक गैर-बूलियन को एक उल्टे बूलियन में परिवर्तित करता है (उदाहरण के लिए, 5 गलत होगा, क्योंकि 5 जेएस में एक गैर-गलत मूल्य है), फिर बूलियन-यह बताता है कि आपको मूल मूल्य एक बूलियन के रूप में मिलता है (इसलिए! 5) सच हो)।
चक

111
इसका वर्णन करने का एक आसान तरीका है: बुलियन (5) === !! 5; वही कास्टिंग, कम किरदार।
मीका स्नाइडर

39
इसका उपयोग सत्य मूल्यों को बूलियन सच में बदलने के लिए किया जाता है, और मिथ्या मूल्य भी बूलियन असत्य है।
Thetoolman

13
@ मीका स्नाइडर सावधान रहें कि जावास्क्रिप्ट में यह बूलियन प्राइमेटिव का उपयोग करने के बजाय नई बूलियन () के साथ बॉक्स बूलियन ऑब्जेक्ट बनाने के लिए बेहतर है। यहाँ अंतर देखने के लिए एक उदाहरण है: jsfiddle.net/eekbu
winorvartan

4
जहाँ तक मुझे पता है, यह बैंग-बैंग पैटर्न अगर (… _ कथन) के अंदर उपयोगी नहीं है, केवल एक फ़ंक्शन के रिटर्न स्टेटमेंट में, जो एक बूलियन को वापस करना चाहिए।
rds

853

यह एक प्रकार का रूपांतरण करने के लिए बहुत ही अस्पष्ट तरीका है।

!है नहीं । तो !trueहै false, और !falseहै true!0है true, और !1है false

तो आप एक बूलियन के लिए एक मूल्य परिवर्तित कर रहे हैं, फिर इसे inverting, फिर इसे inverting।

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

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

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

73
!! झूठा = झूठा। !! सच = सच
क्लैपसे

89
क्या "समझने में बहुत आसान है" संस्करण वास्तव में यहाँ समझने में बहुत आसान है? 0 के खिलाफ चेक 0 के खिलाफ एक वास्तविक चेक नहीं है, लेकिन कुछ हद तक अजीब मानों की जावास्क्रिप्ट के खिलाफ एक चेक 0. के बराबर समझता है userId ? true : false कि अधिक रूपांतरण है जो चल रहा है और उस मामले को संभालता है जहां उपयोगकर्ता का मान स्पष्ट रूप से सेट किया गया हो सकता हैundefined
बेन रिजेन्स्पैन

54
मेरे मस्तिष्क डिकोडिंग किसी भी समस्या नहीं है !!varमें Boolean(var).. और !!तेजी से (प्रक्रिया के लिए कम निर्देश) और विकल्प की तुलना में कम है।
adamJLev

7
@ रिकी क्लार्कसन मुख्य रूप से पठनीयता के लिए है क्योंकि वाक्य-रचना के लिए इसकी आवश्यकता नहीं है। कुछ इसे हमेशा अभिव्यक्ति के बाकी हिस्सों से अलग करने के लिए कोष्ठक में एक सशर्त लपेटने के सम्मेलन का उपयोग करते हैं।
डेव रैगर

8
मैं इससे असहमत हूं। userId != 0के लिए सच है null, NaNऔर undefined, लेकिन झूठे के लिए false। यदि आप वास्तव में ऐसा व्यवहार चाहते हैं, तो आपको इसके बारे में स्पष्ट होना चाहिए। लेकिन यहां तक ​​कि अगर यह बिल्कुल उसी तरह काम करता है !!userId, तो यह स्पष्ट नहीं है कि क्या आप चाहते हैं कि वे मूल्य यहां झूठे हों, या क्या आप जावास्क्रिप्ट के रूपांतरण नियमों पर विचार करने में विफल रहे।
दर्शन

449

!!exprअभिव्यक्ति की सत्यता के आधार पर एक बूलियन मान ( trueया false) देता है । गैर-बूलियन प्रकारों पर उपयोग किए जाने पर यह अधिक समझ में आता है। इन उदाहरणों पर विचार करें, विशेष रूप से 3 उदाहरण और आगे:

          !!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
वर्थ नोटिंग:!!new Boolean(false) // true
कैमिलो मार्टिन

43
... लेकिन यह भी!!Boolean(false) // false
कैमिलो मार्टिन

97
new Boolean(false)एक वस्तु है और एक वस्तु सत्य है भले ही उसमें मिथ्या मूल्य हो!
सलमान ए

3
हाँ मैं जानता हूँ कि, लेकिन सच है कि अधिकांश देशी कंस्ट्रक्टर्स (पर विचार String, Number, Date, आदि) भी कार्य के रूप में प्रतिदेय के लिए हैं, फिर भी इस मामले में परिणाम अलग है!
कैमिलो मार्टिन

4
@CamiloMartin: सिर्फ महसूस किया कि new Boolean(false)रिटर्न एक objectजबकि Boolean(false)रिटर्न आदिम false । आशा है कि यह समझ में आता है।
सलमान एक

155

कुछ चाय पिलाई:

!!संचालक नहीं है। यह दोहरे उपयोग का है !- जो तार्किक "नहीं" ऑपरेटर है।


सिद्धांत रूप में:

! "सच" निर्धारित करता है कि मूल्य क्या नहीं है:

  • सच्चाई यह है कि falseऐसा नहीं है true(इसीलिए !falseपरिणाम true)

  • सच्चाई यह है कि trueऐसा नहीं है false(इसीलिए !trueपरिणाम false)


!!निर्धारित करता है कि क्या एक मूल्य है की "सच" नहीं नहीं:

  • सच्चाई यह है कि trueऐसा नहीं है true (इसीलिए इसमें !!trueपरिणाम है true)

  • सच्चाई यह है कि falseऐसा नहीं है false (इसीलिए इसमें !!falseपरिणाम है false)


तुलना में हम जो निर्धारित करना चाहते हैं , वह संदर्भ के मूल्य के बारे में "सत्य" है , न कि केवल संदर्भ का मूल्य । एक उपयोग-मामला है जहां हम एक मूल्य के बारे में सच्चाई जानना चाहते हैं, भले ही हम मूल्य false(या गलत) होने की उम्मीद करते हैं, या यदि हम उम्मीद करते हैं कि मूल्य टाइपोफ़ नहीं है boolean


प्रयोग में:

एक गतिशील फ़ंक्शन पर विचार करें जो गतिशील टाइपिंग के माध्यम से सुविधा कार्यक्षमता (और इस मामले में, मंच संगतता) का पता लगाता है (उर्फ "बतख टाइपिंग")। हम एक फ़ंक्शन लिखना चाहते हैं जो trueअगर उपयोगकर्ता के ब्राउज़र एचटीएमएल 5 <audio>तत्व का समर्थन करता है, तो वापस आ जाता है , लेकिन हम यह नहीं चाहते कि फ़ंक्शन <audio>अपरिभाषित होने पर त्रुटि को फेंक दे ; और हम try ... catchकिसी भी संभावित त्रुटियों को संभालने के लिए उपयोग नहीं करना चाहते हैं (क्योंकि वे सकल हैं); और इसके अलावा, हम फ़ंक्शन के अंदर एक चेक का उपयोग नहीं करना चाहते हैं जो लगातार फीचर के बारे में सच्चाई को प्रकट नहीं करेगा (उदाहरण के लिए, document.createElement('audio')अभी भी एक तत्व बना देगा जिसे <audio>एचटीएमएल 5 <audio>समर्थित नहीं है)।


यहाँ तीन दृष्टिकोण हैं:

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

प्रत्येक फ़ंक्शन ए <tag>और ए की तलाश के लिए एक तर्क को स्वीकार करता है attribute, लेकिन वे प्रत्येक तुलना के आधार पर विभिन्न मूल्यों को वापस करते हैं।

लेकिन रुकिए, और भी है!

आप में से कुछ शायद यह है कि इस विशिष्ट उदाहरण में, एक बस एक संपत्ति थोड़ा प्रयोग करने के लिए जांच कर सकता है पर ध्यान अधिक performant पता चल सके कि प्रश्न में वस्तु के साधन है एक संपत्ति। इसे करने के दो तरीके हैं:

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

हम पचा ...

हालांकि दुर्लभ ये स्थितियां हो सकती हैं, कुछ परिदृश्य मौजूद हो सकते हैं जहां सबसे संक्षिप्त, सबसे अधिक प्रदर्शनकारी, और इस प्रकार trueगैर-बूलियन से प्राप्त होने का सबसे पसंदीदा साधन , संभवतः अपरिभाषित मूल्य वास्तव में उपयोग करके है !!। उम्मीद है कि यह हास्यास्पद रूप से इसे साफ करता है।


1
पूरी तरह से भयानक जवाब है, लेकिन मैं की उपयोगिता को देखने के लिए असफल !! निर्माण। चूंकि एक if()बयान पहले से ही बूलियन के लिए अभिव्यक्ति देता है, इसलिए स्पष्ट रूप से बूलियन के लिए परीक्षण फ़ंक्शन के रिटर्न मूल्य को कास्टिंग करना निरर्थक है - चूंकि "सत्यता" === सच है जहां तक ​​एक if()बयान वैसे भी जाता है। या मैं एक परिदृश्य याद कर रहा हूँ जहाँ आपको वास्तव में बूलियन होने के लिए एक सत्य अभिव्यक्ति की आवश्यकता है true?
टॉम ऑस्टर

1
@TomAuger if()स्टेटमेंट फाल्सी वैल्यूज के खिलाफ बुलियन कास्ट करते हैं, लेकिन कहते हैं कि आप वास्तव में एक ऑब्जेक्ट पर एक बूलियन फ्लैग सेट करना चाहते हैं - यह एक if()स्टेटमेंट की तरह इसे कास्ट नहीं करेगा । उदाहरण के लिए वास्तविक रिटर्न मान के बजाय या object.hasTheThing = !!castTheReturnValToBoolNoMatterWhat()तो सेट किया जाएगा । एक अन्य उदाहरण शायद सभी प्रवेशकों का है और गैर-व्यवस्थापक आईडी या उच्चतर हैं। यह पाने के लिए कि कोई ऐसा व्यक्ति नहीं है जो आप कर सकते हैं । कुछ मामलों का उपयोग करें, लेकिन जब वहाँ है यह संक्षिप्त है। truefalseid01trueperson.isNotAdmin = !!admin.id
बेनी

103

!!मूल्य को उसके समतुल्य बूलियन मान में परिवर्तित करता है। (गरीब आदमी के "टाइप-कास्टिंग" के तरीके पर विचार करें)। इसका आशय आम तौर पर पाठक को यह बताना होता है कि कोड को इस बात की परवाह नहीं है कि चर में क्या मूल्य है, लेकिन यह "सत्य" मूल्य क्या है।


4
या दाईं ओर एक बूलियन मान के मामले में, यह कुछ भी नहीं करता है।
डैनियल ए। व्हाइट

3
@ डैनियल: !अभी भी मूल्य को दाईं ओर फ़्लिप करता है। एक बूलियन के मामले में सही-सबसे अधिक !मूल्य की उपेक्षा करता है, जबकि बाईं ओर-सबसे !इसे एक बार फिर से नकार देता है। शुद्ध प्रभाव यह है कि कोई बदलाव नहीं हुआ है, लेकिन अधिकांश इंजन दोहरे नकार के लिए ऑप कोड उत्पन्न करेंगे।
वर्धमान ताजा

पर बात क्या है? अगर मैं if(0){...जावास्क्रिप्ट करता हूं तो पहले से ही पता है कि यह गलत है। यह कहना बेहतर क्यों है if(!!0){...?
कॉडीबगस्टीन

बिंदु चर के लिए है कि आप इसकी सामग्री को नहीं जान सकते हैं; यदि यह एक पूर्णांक या एक स्ट्रिंग, एक वस्तु या अशक्त, अपरिभाषित आदि हो सकता है, तो यह अस्तित्व का परीक्षण करने का एक आसान तरीका है।
मिक्स 3 डी।

71

!!fooयूनियरी ऑपरेटर को दो बार लागू नहीं करता है और इसका उपयोग बूलियन प्रकार के लिए कास्ट करने के लिए किया जाता है जैसे कि यूनरी प्लस +fooका उपयोग संख्या में डालने और रिक्त स्ट्रिंग ''+fooको स्ट्रिंग करने के लिए एक खाली स्ट्रिंग को जोड़ने के लिए किया जाता है।

इन हैक्स के बजाय, आप स्पष्ट रूप से डाले गए मानों के लिए आदिम प्रकारों ( बिना उपयोग किएnew ) के अनुरूप निर्माण कार्यों का उपयोग कर सकते हैं , अर्थात

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

लेकिन फिर आप इश्यूफ के साथ मुद्दों में भाग सकते हैं। नई बूलियन (1) इंस्टोफ़ ऑब्जेक्ट -> सच !! 1 इंस्टाफॉफ़ ऑब्जेक्ट -> झूठी
सीमस

13
नहीं, आप नहीं कर सकते हैं: ध्यान दें कि निर्माण कार्यों को बिना बुलाया जाता है new- जैसा कि मेरे उत्तर में स्पष्ट रूप से उल्लेख किया गया है
क्रिस्टोफ़

2
बहुत खुबस! यह थोड़ा हैक के लिए उपयोगी है जब आपको "0" के साथ स्ट्रिंग्स का मूल्यांकन करने की आवश्यकता होती है क्योंकि यह सच के बजाय झूठ है। (यानी जब चयनों से मान पढ़ना, क्योंकि उन्हें स्ट्रिंग के रूप में पढ़ा जाता है)। इसलिए, यदि आप "0" को ऋणात्मक (बूलियन असत्य) मानना ​​चाहते हैं, तो मान x="0"लें कि: x=!!+x; //falseजो कि Boolean(Number(x))संख्या के समान है (या + x) स्ट्रिंग "0" को 0 में परिवर्तित करता है, जो झूठे का मूल्यांकन करता है, और फिर बूलियन (!! x) इसे सीधे बूलियन में डालता है। बहुत आसान!
डिएगोडीडी

2
@DiegoDD आप !!+xबनाम क्यों चुनेंगे x !== "0"?
प्लेसीबॉर्डो

@placeyordordeaux क्योंकि उदाहरण के लिए आप मान को परिवर्तित करना चाहते हैं और इसे अन्य चर में असाइन कर सकते हैं, भले ही आप इसकी तुलना किसी और चीज़ से करने जा रहे हों या नहीं।
डिएगोडीडी

67

इतने सारे जवाब आधे काम कर रहे हैं। हां, !!X"X की सत्यता [एक बूलियन के रूप में प्रतिनिधित्व]" के रूप में पढ़ा जा सकता है। लेकिन !!, व्यावहारिक रूप से बोलना, इतना महत्वपूर्ण नहीं है कि एक एकल चर है (या यहां तक ​​कि अगर कई चर हैं) सत्य या झूठ है। !!myVar === trueबस के रूप में ही है myVar!!X"वास्तविक" बूलियन की तुलना वास्तव में उपयोगी नहीं है।

आप जो हासिल करते हैं !!वह एक दोहराए जाने वाले, मानकीकृत (और JSLint अनुकूल) फैशन में एक दूसरे के खिलाफ कई चर की सत्यता की जांच करने की क्षमता है ।

बस कास्टिंग :(

अर्थात्...

  • 0 === falseहै false
  • !!0 === falseहै true

ऊपर का इतना उपयोगी नहीं है। if (!0)आप के रूप में एक ही परिणाम देता है if (!!0 === false)। मैं एक चर को बूलियन में डालने और फिर "सच्चे" बूलियन से तुलना करने के लिए एक अच्छे मामले के बारे में नहीं सोच सकता।

JSLint के निर्देशों से "== और! =" देखें (ध्यान दें: क्रॉकफ़ोर्ड अपनी साइट को थोड़ा आगे बढ़ा रहा है; कुछ पर मरने के लिए यह लिंक उत्तरदायी है):

तुलना करने से पहले == और = = ऑपरेटर प्रकार की ज़बरदस्ती करते हैं। यह बुरा है क्योंकि यह 't \ r \ n' == 0 को सत्य बनाता है। यह प्रकार की त्रुटियों को मुखौटा कर सकता है। JSLint मज़बूती से यह निर्धारित नहीं कर सकता है कि == का उपयोग सही ढंग से किया जा रहा है, इसलिए = = और! = का उपयोग नहीं करना सबसे अच्छा है और इसके बजाय हमेशा अधिक विश्वसनीय === और = = ऑपरेटरों का उपयोग करें।

यदि आप केवल इस बात का ध्यान रखते हैं कि मूल्य सत्य या मिथ्या है, तो संक्षिप्त रूप का उपयोग करें। के बजाय
(foo != 0)

सिर्फ कहे
(foo)

और के बजाय
(foo == 0)

कहते हैं
(!foo)

ध्यान दें कि कुछ अनूठे मामले हैं जहां एक नंबर के लिए एक बूलियन की तुलना में एक बूलियन को एक नंबर पर डाल दिया जाएगा ( trueको 1और उसके बाद )। इस मामले में, मानसिक रूप से उपयोगी हो सकता है। हालांकि, फिर से, ये ऐसे मामले हैं जहां आप एक गैर-बूलियन की तुलना एक कठिन-टाइप बूलियन से कर रहे हैं, जो कि, एक गंभीर गलती है। अभी भी यहाँ जाने का रास्ता है।false0!! if (-1)

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

और चीजें आपके इंजन के आधार पर भी चरमरा जाती हैं। उदाहरण के लिए, WScript, पुरस्कार जीतता है।

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

वजह से कुछ ऐतिहासिक विंडोज जाइव , कि करेंगे उत्पादन -1 संदेश बॉक्स में! इसे cmd.exe प्रॉम्प्ट में आज़माएँ और देखें! लेकिन फिर WScript.echo(-1 == test())भी आपको 0 या WScript की सुविधा मिलती है falseदूर देखो। यह छुपा हुआ है।

सत्य की तुलना :)

लेकिन क्या होगा अगर मेरे पास दो मूल्य हैं जो मुझे समान ट्रूथी / फालसी-नेस के लिए जांचने की आवश्यकता है?

हमारे पास बहाना है myVar1 = 0;और myVar2 = undefined;

  • myVar1 === myVar2है 0 === undefinedऔर स्पष्ट रूप से गलत है।
  • !!myVar1 === !!myVar2है !!0 === !!undefinedऔर सच है! एक ही सत्यता! (इस मामले में, दोनों "झूठेपन की सच्चाई है"।)

तो एकमात्र स्थान जिसे आपको वास्तव में "बूलियन-कास्ट वैरिएबल" का उपयोग करने की आवश्यकता होगी, यदि आपके पास ऐसी स्थिति है जहां आप जांच कर रहे हैं कि क्या दोनों चरों की सत्यता समान है , है ना? यही है, उपयोग करें !!यदि आपको यह देखने की आवश्यकता है कि क्या दो संस्करण सत्य हैं या दोनों मिथ्या (या नहीं) हैं, अर्थात, समान (या नहीं) सत्यता

मैं उस अपमान के लिए एक महान, गैर-कंट्रास्टेड उपयोग के मामले के बारे में नहीं सोच सकता। हो सकता है कि आपके पास एक रूप में "लिंक" फ़ील्ड हैं?

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

तो अब अगर आपके पास पति या पत्नी दोनों के नाम के लिए सच्चाई है या उम्र और उम्र दोनों के लिए गलत है, तो आप जारी रख सकते हैं। अन्यथा आपको केवल एक फ़ील्ड मिला है जिसमें एक मान है (या बहुत जल्दी की गई शादी) और आपके errorObjectsसंग्रह पर एक अतिरिक्त त्रुटि बनाने की आवश्यकता है ।


EDIT 24 अक्टूबर 2017, 6 फरवरी 19:

3 पार्टी पुस्तकालय जो स्पष्ट बूलियन मूल्यों की अपेक्षा करते हैं

यहां एक दिलचस्प मामला है ... !!उपयोगी तब हो सकता है जब 3 पार्टी के कार्य स्पष्ट बूलियन मूल्यों की अपेक्षा करते हैं।

उदाहरण के लिए, जेएसएक्स (रिएक्ट) में गलत का एक विशेष अर्थ है जो सरल मिथ्या पर नहीं चलता है। यदि आपने अपने JSX में निम्नलिखित की तरह कुछ लौटाने की कोशिश की है, तो एक int की उम्मीद है messageCount...

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

... 0जब आप शून्य संदेश देते हैं, तो रिएक्ट रेंडर देखकर आपको आश्चर्य हो सकता है । आपको स्पष्ट रूप से JSX को रेंडर न करने के लिए स्पष्ट रूप से वापस लौटना होगा। उपरोक्त कथन लौटाता है 0, जिसे JSX खुशी से प्रस्तुत करता है, जैसा कि इसे करना चाहिए। यह नहीं बता सकता है कि आपके पास Count: {messageCount && <div>Get your count to zero!</div>}(या कुछ कम वंचित) नहीं है।

  • एक फिक्स में बैंगबैंग शामिल है, जो इसमें समाहित 0है !!0, जो है false:
    {!!messageCount && <div>You have messages!</div>}

  • JSX के डॉक्स आपको अधिक स्पष्ट होने का सुझाव देते हैं, स्व-टिप्पणी कोड लिखते हैं, और एक बूलियन के लिए मजबूर करने के लिए तुलना का उपयोग करते हैं।
    {messageCount > 0 && <div>You have messages!</div>}

  • मैं और अधिक आराम से अपने आप को एक त्रिगुट के साथ झूठा निपटने में सक्षम हूं -
    {messageCount ? <div>You have messages!</div> : false}

टाइपस्क्रिप्ट में समान सौदा: यदि आपके पास एक फ़ंक्शन है जो एक बूलियन लौटाता है (या आप बूलियन चर के लिए एक मूल्य प्रदान कर रहे हैं), तो आप [आमतौर पर] एक बूलियन-वाई मान वापस नहीं कर सकते / असाइन नहीं कर सकते हैं; यह एक जोरदार टाइप बूलियन होना है। इसका मतलब है, अगर iff myObjectको जोरदार टाइप किया जाता है , तो return !myObject;बूलियन को लौटाने वाले फ़ंक्शन के लिए काम करता है, लेकिन return myObject;ऐसा नहीं करता है। आपको return !!myObjectटाइपस्क्रिप्ट की अपेक्षाओं से मेल खाना है।

टाइपस्क्रिप्ट के लिए अपवाद? यदि आप myObjectएक थे any, तो आप जावास्क्रिप्ट वाइल्ड वेस्ट में वापस आ गए और इसे वापस कर सकते हैं !!, भले ही आपका रिटर्न प्रकार एक बूलियन हो।

ध्यान रखें कि ये JSX और टाइपस्क्रिप्ट कन्वेंशन हैं , जावास्क्रिप्ट के लिए अंतर्निहित नहीं हैं

लेकिन अगर आपको 0अपने रेंडर किए गए JSX में अजीब सा लगता है, तो ढीले झूठे प्रबंधन के बारे में सोचें।


अच्छे खर्च। तो क्या आप कहेंगे !! इस कार्यकर्ता सुविधा का पता लगाने के उदाहरण में कड़ाई से आवश्यक नहीं है ? if (!!window.Worker)
jk7

2
नहीं, आपको इसकी आवश्यकता नहीं होगी। सत्यता और true"बाह्य रूप से" एक ही में संचालित होते हैं if। मैं कोशिश करता रहता हूं, लेकिन मैं एक कारण के बारे में नहीं सोच सकता हूं कि सत्यता की तुलना में बूलियन मान के लिए कास्टिंग सत्यता को प्राथमिकता दें "सत्यता की तुलना करें" मामला, ऊपर, पठनीयता को छोड़कर अगर आप बाद में मूल्य का पुन: उपयोग करते हैं, तो qलाइब्रेरी उदाहरण के रूप में । लेकिन फिर भी, यह एक सूचना-दोषपूर्ण शॉर्टकट है, और मैं तर्क देता हूं कि आप हर बार सच्चाई का मूल्यांकन करना बेहतर समझते हैं।
रफिन

प्रतिक्रिया मुख्य कारण है जिसका हमने उपयोग करना शुरू कर दिया है !! पैटर्न, लेकिन यह एक बहुत ही सुविधाजनक और दोहराव वाली बात होती है। मुझे केवल किसी चीज़ की सत्यता या अस्वस्थता के बारे में चिंता करना है, न कि यह कि अंतर्निहित प्रकार क्या है।

टिप्पणियों के बिना डाउनवोट्स को आपकी चिंता का समाधान करना मुश्किल है! मुझे बताएं कि क्या बुरा लग रहा है, और मुझे इसे संबोधित करने में खुशी होगी।
रफिन

55

यह सिर्फ तार्किक नहीं ऑपरेटर है, दो बार - इसका उपयोग कुछ बूलियन में बदलने के लिए किया जाता है, जैसे:

true === !!10

false === !!0

3
पृथ्वी पर आप ऐसा क्यों करेंगे? उपयोग ! ऑपरेटर बूलियन में कनवर्ट करने के लिए === का उपयोग करने के लिए प्रकार की तुलना करें? बस स्वीकार करें कि आपके पास कोई प्रकार की सुरक्षा नहीं है और वैल> 0 या कुछ और करें।
डैरेन क्लार्क

43
@ डैरेन: वह प्रकारों की तुलना नहीं कर रहा है; वह आपको बता रहा है कि उसके जवाब में मुखरता से लिखकर परिणाम क्या हैं।
ऑर्बिट


26

यह दोहरा notऑपरेशन है। पहले !मूल्य को बूलियन में परिवर्तित करता है और इसके तार्किक मूल्य को बदल देता है। दूसरा !तार्किक मान वापस लौटाता है।


26

ऐसा लगता है कि !!ऑपरेटर एक दोहरे नकार में परिणाम करता है।

var foo = "Hello World!";

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

23

यह Boolean()कास्टिंग फ़ंक्शन के व्यवहार का अनुकरण करता है। पहला NOTबूलियन मान लौटाता है, चाहे वह किसी भी तरह का हो। दूसरा NOTउस Booleanमूल्य को नकारता है और इसलिए trueएक चर का बूलियन मूल्य देता है । अंतिम परिणाम Boolean()मान पर फ़ंक्शन का उपयोग करने के समान है ।


20

! "बूलियन नहीं" है, जो अनिवार्य रूप से इसके बूलियन के विपरीत "सक्षम" के मूल्य को टाइपकास्ट करता है। द्वितीय ! इस मान को फ़्लिप करता है। तो, !!enableइसका अर्थ है "सक्षम नहीं," आपको enableबूलियन के रूप में मूल्य देना ।


18

मुझे लगता है कि उल्लेख के लायक है, कि तार्किक और / या के साथ संयुक्त एक शर्त एक बूलियन मान नहीं लौटेगी, लेकिन अंतिम सफलता या पहली & # या के मामले में पहली सफलता या अंतिम असफलता || हालत श्रृंखला की।

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

शर्त को एक सच्चे बूलियन शाब्दिक में डालने के लिए हम दोहरे नकार का उपयोग कर सकते हैं:

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

17

!!यह NOTएक साथ दो बार ऑपरेशन का उपयोग कर रहा है, !मान को एक में परिवर्तित करें booleanऔर इसे उलट दें, यहां एक सरल उदाहरण है कि कैसे !!काम करता है:

सबसे पहले, आपके पास जगह:

var zero = 0;

फिर आप करते हैं !0, इसे बूलियन में बदल दिया जाएगा और इसका मूल्यांकन किया जाएगा true, क्योंकि 0 है falsy, इसलिए आप उलटा मूल्य प्राप्त करते हैं और बूलियन में परिवर्तित होते हैं, इसलिए इसका मूल्यांकन किया जाता है true

!zero; //true

लेकिन हम मूल्य का उलटा बूलियन संस्करण नहीं चाहते हैं , इसलिए हम अपना परिणाम प्राप्त करने के लिए इसे फिर से उलट सकते हैं! इसलिए हम दूसरे का उपयोग करते हैं !

मूल रूप से, !!हमें सुनिश्चित करें कि हमें जो मूल्य मिल रहा है वह बूलियन है, मिथ्या नहीं, सत्य या स्ट्रिंग आदि ...

तो यह Booleanजावास्क्रिप्ट में फ़ंक्शन का उपयोग करने जैसा है , लेकिन मूल्य को बूलियन में बदलने का आसान और छोटा तरीका:

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

15

!!निर्माण अपने बूलियन बराबर में किसी भी जावास्क्रिप्ट अभिव्यक्ति मोड़ का एक सरल तरीका है।

उदाहरण के लिए: !!"he shot me down" === trueऔर !!0 === false


2
महत्वपूर्ण अंतर के बहुत करीब। कुंजी यह है कि 0 === falseगलत है और !!0 === falseसच है।
रफिन

14

यह एक ऑपरेटर नहीं है, यह दो है। यह निम्नलिखित के बराबर है और बूलियन के लिए मूल्य डालने का एक त्वरित तरीका है।

val.enabled = !(!enable);

10

मुझे संदेह है कि यह C ++ से बचे हुए हैं जहां लोग ओवरराइड करते हैं! ऑपरेटर लेकिन बूल ऑपरेटर नहीं।

तो उस स्थिति में नकारात्मक (या सकारात्मक) उत्तर प्राप्त करने के लिए आपको सबसे पहले उपयोग करने की आवश्यकता होगी! एक बूलियन प्राप्त करने के लिए ऑपरेटर, लेकिन अगर आप सकारात्मक मामले की जांच करना चाहते थे तो !!।


10

ifऔर whileबयानों और ?ऑपरेटर उपयोग सच मान कोड की किस शाखा निर्धारित करने के लिए चलाने के लिए। उदाहरण के लिए, शून्य और NaN संख्याएँ और खाली स्ट्रिंग गलत हैं, लेकिन अन्य संख्याएँ और तार सही हैं। वस्तुएं सत्य हैं, लेकिन अपरिभाषित मूल्य और nullदोनों झूठे हैं।

दोहरा नकार ऑपरेटर !!मूल्य के सत्य मूल्य की गणना करता है। यह वास्तव में दो ऑपरेटर हैं, जहां !!xइसका मतलब है !(!x), और निम्नानुसार व्यवहार करता है:

  • यदि xएक गलत मान है, !xहै true, और !!xहै false
  • अगर xएक सही मूल्य है, !xहै false, और !!xहै true

जब एक बूलियन संदर्भ के शीर्ष स्तर पर इस्तेमाल किया ( if, while, या ?), !!ऑपरेटर व्यवहार के आधार पर नो-सेशन है। उदाहरण के लिए, if (x)और if (!!x)एक ही बात का मतलब है।

व्यावहारिक उपयोग

हालाँकि इसके कई व्यावहारिक उपयोग हैं।

एक उपयोग नुकसानदेह वस्तु को उसके सत्य मान को संपीड़ित करने के लिए है, ताकि आपका कोड किसी बड़ी वस्तु का संदर्भ न रखे और उसे जीवित रखे। कचरा संग्राहक के लिए इसे जाने के !!some_big_objectबजाय एक चर को असाइन करना some_big_object। यह उन मामलों के लिए उपयोगी है जो किसी वस्तु या गलत मूल्य जैसे कि nullया अपरिभाषित मूल्य का उत्पादन करते हैं, जैसे कि ब्राउज़र सुविधा का पता लगाना।

एक अन्य उपयोग, जिसका मैंने सी के संगत !!ऑपरेटर के बारे में एक उत्तर में उल्लेख किया है , "लिंट" टूल के साथ है जो सामान्य टाइपो और प्रिंट डायग्नोस्टिक के लिए देखते हैं। उदाहरण के लिए, सी और जावास्क्रिप्ट दोनों में, बूलियन ऑपरेशन के लिए कुछ सामान्य टाइपोस अन्य व्यवहारों का उत्पादन करते हैं जिनका उत्पादन बुलियन के रूप में काफी नहीं है:

  • if (a = b)सच मान के उपयोग के बाद असाइनमेंट है b; if (a == b)एक समानता तुलना है।
  • if (a & b)एक बिटवाइज़ है और; if (a && b)एक तार्किक है। 2 & 5है 0(एक गलत मूल्य); 2 && 5सच हैं।

!!ऑपरेटर फाहा उपकरण आश्वस्त क्या आप ने लिखा है कि तुम क्या मतलब है कि: है इस आपरेशन, तो परिणाम की सच्चाई मान ले।

एक तीसरा उपयोग तार्किक XOR और तार्किक XNOR का उत्पादन करना है। C और जावास्क्रिप्ट दोनों में, a && bएक तार्किक AND (सत्य यदि दोनों पक्ष सत्य हैं) a & bकरता है , और एक बिटवाइंड AND करता है। a || bतार्किक या (सही है तो कम से कम एक सच है) a | bकरता है , और एक बिटवाइस या करता है। एक बिटवाइज़ XOR (एक्सक्लूसिव OR) है a ^ b, लेकिन लॉजिकल XOR के लिए बिल्ट-इन ऑपरेटर नहीं है (सच यदि एक तरफ सच है)। उदाहरण के लिए, आप उपयोगकर्ता को दो क्षेत्रों में से एक में पाठ दर्ज करने की अनुमति देना चाहते हैं। आप जो कर सकते हैं, वह प्रत्येक को एक सत्य मूल्य में परिवर्तित करता है और उनकी तुलना करता है !!x !== !!y:।


8

डबल बूलियन नकार। अक्सर यह जांचने के लिए उपयोग किया जाता है कि क्या मूल्य अपरिभाषित नहीं है।


8

यहाँ महान जवाब के टोंस, लेकिन अगर आप इसे दूर पढ़ते हैं, तो इससे मुझे 'इसे प्राप्त करने' में मदद मिली। Chrome (आदि) पर कंसोल खोलें, और टाइप करना शुरू करें:

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

स्वाभाविक रूप से, ये सभी केवल टाइपिंग के समान हैं! कुछ। लेकिन जोड़े गए कोष्ठक इसे और अधिक समझने में मदद कर सकते हैं।


8

!!x के लिए आशुलिपि है Boolean(x)

पहला धमाका js इंजन को चलाने के लिए मजबूर करता है, Boolean(x)लेकिन साथ ही मूल्य को प्रभावित करने का दुष्प्रभाव भी है। तो दूसरा धमाका साइड इफेक्ट को कम करता है।


8

यह सभी चीजों को बूलियन के लिए मजबूर करता है।

उदाहरण के लिए:

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

इस सवाल का बहुत अच्छी तरह से जवाब दिया गया है, लेकिन मैं एक जवाब जोड़ना चाहूंगा कि मुझे आशा है कि जितना संभव हो उतना सरल बनाया जाए, !! जितना हो सकता है उतना सरल है।

क्योंकि जावास्क्रिप्ट में "सत्य" और "गलत" मूल्यों को कहा जाता है, ऐसे भाव हैं कि जब अन्य अभिव्यक्तियों का मूल्यांकन किया जाता है तो एक सही या गलत स्थिति होगी, भले ही मूल्य या अभिव्यक्ति की जांच की जा रही हो, वास्तव में trueया नहीं false

उदाहरण के लिए:

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

यदि वह तत्व वास्तव में मौजूद है, तो अभिव्यक्ति सही के रूप में मूल्यांकन करेगी, और कोड ब्लॉक निष्पादित किया जाएगा।

तथापि:

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

... एक वास्तविक स्थिति में परिणाम नहीं होगा, और कोड ब्लॉक निष्पादित नहीं किया जाएगा, भले ही तत्व मौजूद हो।

क्यों? क्योंकि document.getElementById()एक "सत्य" अभिव्यक्ति है जो इस if()कथन में सत्य के रूप में मूल्यांकन करेगी , लेकिन यह वास्तविक बूलियन मूल्य नहीं है true

इस मामले में डबल "नहीं" काफी सरल है। यह बस दो notबैक टू बैक है।

पहले एक बस "अशुद्ध" सत्य या गलत मूल्य, जिसके परिणामस्वरूप एक वास्तविक बूलियन प्रकार होता है, और फिर दूसरा एक "अकशेरुकी" यह फिर से मूल स्थिति में वापस आ जाता है, लेकिन अब एक वास्तविक बूलियन मूल्य में। इस तरह से आपके पास स्थिरता है:

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

तथा

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

उम्मीद के मुताबिक, बीओटीएच सच लौटाएगा।


7

मैं बस उसे जोड़ना चाहता था

if(variableThing){
  // do something
}

के समान है

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

लेकिन यह एक मुद्दा हो सकता है जब कुछ अपरिभाषित हो।

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

चाल यहाँ &&s की श्रृंखला है जो पहले पाया गया मान वापस करेगा - और यह एक if स्टेटमेंट आदि को फीड किया जा सकता है, इसलिए यदि b.foo अपरिभाषित है, तो यह अनिर्धारित वापस आ जाएगा और b.foo.barस्टेटमेंट को छोड़ देगा , और हमें नहीं मिलेगा त्रुटि।

उपरोक्त वापसी अपरिभाषित है, लेकिन यदि आपके पास एक खाली स्ट्रिंग, गलत, अशक्त, 0 है, तो अपरिभाषित वे मान लौट आएंगे और जैसे ही हम उन्हें श्रृंखला में सामना करेंगे - []और {}दोनों "सत्य" हैं और हम तथाकथित रूप से जारी रखेंगे " && श्रृंखला "दाईं ओर के अगले मान" पर।

PS एक ही काम करने का एक और तरीका है (b || {}).foo, क्योंकि अगर b अपरिभाषित है, तो b || {}होगा {}, और आप "अपरिभाषित" के भीतर एक मूल्य तक पहुँचने की कोशिश करने के बजाय एक खाली वस्तु (कोई त्रुटि) में एक मूल्य तक पहुंच जाएगा (एक त्रुटि का कारण बनता है) )। तो, (b || {}).fooजैसा है b && b.fooऔर ((b || {}).foo || {}).barजैसा है, वैसा ही है b && b.foo && b.foo.bar


अच्छी बात है - मेरे जवाब को बदल दिया। यह केवल एक वस्तु जब यह तीन स्तरों गहरी नेस्ट है पर होता है, क्योंकि जैसे तुमने कहा था ({}).anythingदे देंगेundefined
रयान टेलर

5

इन सभी महान उत्तरों को देखने के बाद, मैं उपयोग करने के लिए एक और कारण जोड़ना चाहूंगा !!। वर्तमान में मैं कोणीय 2-4 (टाइपस्क्रिप्ट) में काम कर रहा हूं और मैं एक बूलियन वापस करना चाहता हूं falseजब मेरा उपयोगकर्ता प्रमाणित नहीं होता है। यदि वह प्रमाणित नहीं है, तो टोकन nullया स्ट्रिंग होगा ""। मैं कोड के अगले ब्लॉक का उपयोग करके ऐसा कर सकता हूं:

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

4

यहाँ कोणीय js से कोड का एक टुकड़ा है

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

 var rafSupported = !!requestAnimationFrame;

उनका उद्देश्य राशन सेट करना है जो फ़ंक्शन में उपलब्धता के आधार पर सही या गलत पर आधारित है

इसे सामान्य तरीके से जाँच कर प्राप्त किया जा सकता है:

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

कम तरीका उपयोग किया जा सकता है !!

rafSupported = !!requestAnimationFrame ;

इसलिए यदि requestAnimationFrame को एक फ़ंक्शन सौंपा गया है, तो अनुरोध! AimimationFrame गलत और एक और होगा! यह सच होगा

अगर requestAnimationFrame को अपरिभाषित किया गया था, तो अनुरोध! यह असत्य होगा


3

जावास्क्रिप्ट में कुछ ऑपरेटर निहित प्रकार के रूपांतरण करते हैं, और कभी-कभी टाइप रूपांतरण के लिए उपयोग किए जाते हैं।

यूनियरी !ऑपरेटर अपने ऑपरेंड को एक बूलियन में परिवर्तित करता है और इसे नकारता है।

यह तथ्य निम्नलिखित मुहावरे को जन्म देता है जिसे आप अपने स्रोत कोड में देख सकते हैं:

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

3

तार्किक नहीं ऑपरेटर का उपयोग करें दो बार
इसका मतलब है! सही = गलत
और !! सच = सच


3

एक चर के बूलियन मूल्य देता है।

इसके बजाय, Booleanकक्षा का उपयोग किया जा सकता है।

(कृपया कोड विवरण पढ़ें)

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`

अर्थात्, Boolean(X) = !!Xउपयोग में।

कृपया नीचे कोड स्निपेट जांचें et

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.