जावास्क्रिप्ट में, "0" झूठे के बराबर क्यों है, लेकिन जब 'अगर' द्वारा परीक्षण किया जाता है, तो यह अपने आप से गलत नहीं है?


232

निम्नलिखित "0"जावास्क्रिप्ट में झूठा है:

>>> "0" == false
true

>>> false == "0"
true

तो निम्न प्रिंट क्यों करता है "ha"?

>>> if ("0") console.log("ha")
ha

47
"0"एक स्ट्रिंग है, और चूंकि यह खाली नहीं है, इसलिए इसका मूल्यांकन सही है।
डिजिटल प्लेन

8
"0" === false [...] false

3
जावास्क्रिप्ट में एंगस कैरोल की लेख सच्चाई की जाँच करें। javascriptweblog.wordpress.com/2011/02/07/…
timrwood

8
'0'==falseलेकिन '0' एक गलत मूल्य नहीं है (हाँ जावास्क्रिप्ट अजीब हो सकता है)
Linsey

5
@ लिन्से: पूरी "झूठी" और "सच्चाई" बात केवल यह समझाने के लिए थी कि मूल्यों को बूलियंस में कैसे बदला जाता है। जब आप दो मूल्यों की तुलना करते हैं ==, तो वे कभी बूलियंस में परिवर्तित नहीं होते हैं, इसलिए यह लागू नहीं होता है। (रूपांतरण के नियम संख्याओं को परिवर्तित करने के पक्ष में प्रतीत होते हैं।)
मिलीमो

जवाबों:


251

कारण यह है कि जब आप स्पष्ट रूप से करते हैं "0" == false, तो दोनों पक्षों को संख्याओं में परिवर्तित किया जा रहा है, और फिर तुलना की जाती है।

जब आप ऐसा करते हैं: if ("0") console.log("ha")स्ट्रिंग मान का परीक्षण किया जा रहा है। कोई भी गैर-रिक्त स्ट्रिंग है true, जबकि एक रिक्त स्ट्रिंग है false

समान (==)

यदि दो ऑपरेंड एक ही प्रकार के नहीं हैं , तो जावास्क्रिप्ट ऑपरेंड को परिवर्तित करता है, फिर सख्त तुलना लागू करता है। यदि या तो ऑपरेंड एक नंबर या बूलियन है , तो ऑपरेंड संभव होने पर नंबर में बदल जाते हैं; या तो अगर ऑपरेंड एक स्ट्रिंग है , तो अन्य ऑपरेंड को यदि संभव हो तो स्ट्रिंग में बदल दिया जाता है। यदि दोनों ऑपरेंड ऑब्जेक्ट हैं , तो जावास्क्रिप्ट आंतरिक संदर्भों की तुलना करता है जो तब समान होते हैं जब ऑपरेंड मेमोरी में एक ही ऑब्जेक्ट को संदर्भित करते हैं।

( मोज़िला डेवलपर नेटवर्क में तुलना ऑपरेटरों से )


348

समस्या प्रदर्शित करने वाली तालिकाएँ:

सत्य अगर बयान

और == जावास्क्रिप्ट में सभी वस्तु प्रकारों की सत्य तुलना

कहानी का नैतिक उपयोग === पवित्रता प्रदर्शित करने वाली सख्त समानता

टेबल जनरेशन क्रेडिट: https://github.com/dorey/JavaScript-Equality-Table


2
यह मूल्यों के किसी अन्य आदेश के भी बहुत कुछ समझ में आता है gist.github.com/kirilloid/8165660
kirilloid

3
अब से, अगर कोई कहता है कि वह कभी सख्त तुलना ऑपरेटरों का उपयोग नहीं करता है, तो मैं इन तालिकाओं के साथ उसका सामना करूंगा और उसे रोना दूंगा। अभी भी यकीन नहीं है कि मैं NaNहालांकि की अवधारणा को समझ सकता हूं । मेरा मतलब है, typeof NaN // numberलेकिन NaN === NaN // false, हम्म ...
जस्टस रोमिजेन

4
मेरे एक दोस्त ने f.cl.ly/items/3b0q1n0o1m142P1P340P/javascript_equality.html बनाया - ऊपर जैसा ही ग्राफ़ है, लेकिन पढ़ने में थोड़ा आसान है।
लुसी बैन

@JustusRomijn का प्रतिनिधित्व करने के लिए कई मूल्य हैं NaN, इसलिए जब आप 2 NaN की तुलना कर रहे हैं, तो वे अलग-अलग मान हैं (मुझे लगता है)। पहला उद्धरण यहाँ पढ़ें ।
cychoi

4
इन तालिकाओं में गलती है। न तो ==है और न ही ===ऑपरेटर के लिए [], {}, [[]], [0]और [1]मूल्यों सच का मूल्यांकन नहीं है। मेरा मतलब है [] == []और [] === []झूठ भी।
हरबर्टसज

38

यह कल्पना के अनुसार है।

12.5 अगर स्टेटमेंट 
.....

2. यदि बूलियन (GetValue (exprRef)) सत्य है, तो 
ए। पहले कथन का मूल्यांकन करने का परिणाम लौटाएं।
3. और, 
....

युक्ति के अनुसार, टूबलियन, है

सार ऑपरेशन टूबूलियन अपने तर्क को टेबल 11 के अनुसार बुलियन के मान में बदल देता है:

और यह तालिका तार के बारे में यह कहती है:

यहां छवि विवरण दर्ज करें

परिणाम गलत है यदि तर्क खाली स्ट्रिंग है (इसकी लंबाई शून्य है); अन्यथा परिणाम सत्य है

अब, यह समझाने के लिए कि "0" == falseआपको समानता ऑपरेटर को क्यों पढ़ना चाहिए, जो बताता है कि अमूर्त ऑपरेशन से इसका मूल्य GetValue(lref)दाईं ओर के लिए समान है।

जो इस प्रासंगिक भाग का वर्णन करता है:

यदि IsPropertyReference (V) है, तो 
ए। यदि HasPrimitiveBase (V) गलत है, तो आधार के [[प्राप्त करें]] आंतरिक विधि होने दें, अन्यथा प्राप्त करें
नीचे दी गई विशेष विधि [[प्राप्त करें]] आंतरिक विधि हो। 
ख। आधार को इस मान के रूप में उपयोग करके प्राप्त आंतरिक विधि को कॉल करने का परिणाम लौटाएं, और गुजर रहा है
तर्क के लिए GetReferencedName (V)

या दूसरे शब्दों में, एक स्ट्रिंग में एक आदिम आधार होता है, जो आंतरिक प्राप्त करने की विधि को वापस बुलाता है और गलत दिख रहा है।

यदि आप GetValue ऑपरेशन के उपयोग से चीजों का मूल्यांकन करना चाहते हैं ==, यदि आप का उपयोग करके मूल्यांकन करना चाहते हैं , तो ToBooleanउपयोग ===(जिसे "सख्त" समानता ऑपरेटर भी कहा जाता है)


"a string has a primitive base, which calls back the internal get method and ends up looking false"क्या यह सभी तार के लिए सही है?
अजीज पंजाबी

@Interstellar_Coder Section 8.12.3: [[Get]] (P)वर्णन करता है कि यह कैसे काम करता है। यह केवल उन मामलों के लिए सच है जो स्ट्रिंग 0 हैं, क्योंकि यह अन्य आंतरिक कॉल का एक गुच्छा करता है, जिसके परिणामस्वरूप अंततः GetOwnPropertyयह देखता है कि "जो भी" एक डेटा प्रॉपर्टी है, जो तब सभी मानों को वापस कर देता है। यही कारण है कि "0" गलत है, और "ब्ला" सच है। याहू डेवलपर थियेटर पर डगलस क्रॉकफोर्ड के कुछ वीडियो देखें, उन्होंने जावास्क्रिप्ट में "सत्यता" का वर्णन किया है जो कि मैं कुछ कम जटिल हूं। यदि आप समझते हैं कि "सत्य" और "झूठा" का अर्थ क्या है तो आप बॉबसन के उत्तर को तुरंत समझ जाएंगे।
गुप्त

1
मैं कल्पना कहां कर सकता हूं?
user985366

12

यह PHP है जहां स्ट्रिंग "0"गलत है (झूठी-जब-इस्तेमाल-में-बूलियन-संदर्भ)। जावास्क्रिप्ट में, सभी गैर-खाली तार सत्य हैं।

चाल यह है कि ==एक बूलियन के खिलाफ एक बूलियन संदर्भ में मूल्यांकन नहीं करता है, यह संख्या में परिवर्तित होता है, और स्ट्रिंग्स के मामले में दशमलव के रूप में पार्स करके किया जाता है। तो आपको 0सत्यता बूलियन के बजाय नंबर मिलता है true

यह एक बहुत ही खराब भाषा का डिज़ाइन है और यह एक कारण है कि हम दुर्भाग्यपूर्ण ==ऑपरेटर का उपयोग नहीं करने का प्रयास करते हैं । ===इसके बजाय उपयोग करें ।


7
// I usually do this:

x = "0" ;

if (!!+x) console.log('I am true');
else      console.log('I am false');

// Essentially converting string to integer and then boolean.

4

आपके आस-पास के उद्धरण 0इसे एक स्ट्रिंग बनाते हैं, जिसका सही मूल्यांकन किया जाता है।

उद्धरण निकालें और यह काम करना चाहिए।

if (0) console.log("ha") 

सही है, "इसे कैसे काम करें" के बारे में नहीं, लेकिन सवाल यह है कि "ऐसा व्यवहार क्यों किया गया?"
nonopolarity

2

यह सब ECMA स्पेक्स के "0" == falseकारण है ... यहाँ निर्दिष्ट नियमों के कारण http://ecma262-5.com/els5_HTML.htm#Section_11.9.3 ... और if ('0')यहाँ दिए गए नियमों के कारण सही का मूल्यांकन करता है http: / /ecma262-5.com/ELS5_HTML.htm#Section_12.5


मुझे नहीं पता था कि किसी ने किसी साइट की कल्पना को चित्रित किया है ... यह बहुत बढ़िया है! मेरे लिए अधिक PDF नहीं।
गुप्त '

1

"अगर" अभिव्यक्ति सत्यता के लिए परीक्षण करती है, जबकि टाइप-स्वतंत्र समकक्षता के लिए दोहरे-बराबर परीक्षण। एक तार हमेशा सत्य होता है, जैसा कि यहां अन्य लोगों ने बताया है। यदि डबल-बराबर सत्यता के लिए अपने दोनों ऑपरेंड्स का परीक्षण कर रहे थे और फिर परिणामों की तुलना कर रहे थे, तो आपको वह परिणाम मिलेगा जो आप सहज रूप से ग्रहण कर रहे थे, अर्थात ("0" == true) === true। जैसा कि डग क्रॉकफोर्ड अपने उत्कृष्ट जावास्क्रिप्ट: द गुड पार्ट्स में कहते हैं , "नियम जिसके द्वारा [== इसके ऑपरेंड के प्रकारों को सहता है] जटिल और असहनीय हैं .... परिवर्तनशीलता की कमी चिंताजनक है।" यह कहना पर्याप्त है कि एक ऑपरेंड दूसरे से मिलान करने के लिए टाइप-कोर्ड है, और यह "0" समाप्त होता है जिसे एक संख्यात्मक शून्य के रूप में व्याख्या किया जाता है,


1

== इक्विटी ऑपरेटर संख्याओं में बदलने के बाद तर्कों का मूल्यांकन करता है। तो स्ट्रिंग शून्य "0" संख्या डेटा प्रकार और बूलियन झूठी में बदल जाती है संख्या 0. में बदल जाती है तो

"0" == false // true

वही `पर लागू होता है

false == "0" //true

=== सख्त समानता जाँच मूल डेटा प्रकार के साथ तर्कों का मूल्यांकन करती है

"0" === false // false, because "0" is a string and false is boolean

उसी पर लागू होता है

false === "0" // false

में

if("0") console.log("ha");

स्ट्रिंग "0" किसी भी तर्कों के साथ तुलना नहीं कर रहा है, और जब तक या किसी भी तर्कों के साथ तुलना नहीं की जाती है तब तक स्ट्रिंग एक सही मूल्य है। बिलकुल जैसा है

if(true) console.log("ha");

परंतु

if (0) console.log("ha"); // empty console line, because 0 is false

`


1

इसका कारण यह है कि जावास्क्रिप्ट बूलियन संदर्भों और आपके कोड में प्रकार के जोर का उपयोग करता है

if ("0") 

बूलियन संदर्भों में सच के लिए मजबूर किया जाएगा।

जावास्क्रिप्ट में अन्य सत्य मान हैं जो बूलियन संदर्भों में सत्य के लिए मजबूर किए जाएंगे, और इस प्रकार यदि ब्लॉक हैं तो निष्पादित करें: -

if (true)
if ({})
if ([])
if (42)
if ("0")
if ("false")
if (new Date())
if (-42)
if (12n)
if (3.14)
if (-3.14)
if (Infinity)
if (-Infinity)

0
if (x) 

जावास्क्रिप्ट के आंतरिक toBoolean (http://es5.github.com/#x9.2) का उपयोग करते हुए coerces x

x == false

दोनों पक्षों को आंतरिक tonumber coercion (http://es5.github.com/#x9.3) या ऑब्जेक्ट्स के लिए हानिकारक (http://es5.github.com/#x9.1) का उपयोग करने के लिए मजबूर करता है।

पूर्ण विवरण के लिए http://javascriptweblog.wordpress.com/2011/02/07/truth-equality-and-javascript/ देखें

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