जावास्क्रिप्ट में असत्य का मूल्यांकन क्यों ("फू" === नया स्ट्रिंग ("फू")) करता है?


98

मैं स्ट्रिंग मूल्यों की तुलना करते समय हर समय === (ट्रिपल बराबर, सख्त तुलना) का उपयोग शुरू करने जा रहा था, लेकिन अब मुझे लगता है कि

"foo" === new String("foo")

यह गलत है, और इसके साथ भी ऐसा ही है:

var f = "foo", g = new String("foo");
f === g; // false

बेशक:

f == g; // true

तो क्या स्ट्रिंग की तुलना के लिए हमेशा == का उपयोग करने की सिफारिश की जाती है, या हमेशा तुलना करने से पहले चर को स्ट्रिंग में परिवर्तित करें?


6
हो सकता है क्योंकि fooशुद्ध स्ट्रिंग है और new String("foo")ऑब्जेक्ट स्ट्रिंग है
Danilo Valente

पृष्ठभूमि: stackoverflow.com/questions/1646698/…
Pekka

6
यह new Stringप्रयोग करने के बजाय (पूर्ण रूप से व्यर्थ) के साथ तार नहीं बनाने की सलाह दी जाती है==
Esailija

2
कोई भी new String("foo")पहले की तरह जावास्क्रिप्ट में निर्माण का उपयोग क्यों करना चाहेगा ? मैंने कोड में ऐसा कोड कभी नहीं देखा है jQuery ...
रॉबर्ट कोरिटनिक

2
String(obj)अपने "स्ट्रिंग" पैरामीटर को प्राप्त करने के बाद आप बॉक्स को स्ट्रिंग को आदिम में बदलने के लिए उपयोग कर सकते हैं । ("foo" === String(new String("foo"))) === true
ऑरेंजडॉग

जवाबों:


126

"foo"एक स्ट्रिंग आदिम है । (यह अवधारणा C # या Java में मौजूद नहीं है)

new String("foo") बॉक्सिंग स्ट्रिंग ऑब्जेक्ट है।

===ऑपरेटर पुरातन और वस्तुओं पर अलग ढंग से व्यवहार करती है
जब आदिमों (एक ही प्रकार के) की तुलना की जाती है, ===तो यदि वे दोनों समान मूल्य रखते हैं, तो वापस लौट आएंगे।

वस्तुओं की तुलना करते समय, ===केवल उसी वस्तु (संदर्भ द्वारा तुलना) के संदर्भ में सही होने पर वापस आ जाएगी। इस प्रकार, new String("a") !== new String("a")

आपके मामले में, ===गलत रिटर्न देता है क्योंकि ऑपरेंड विभिन्न प्रकार के होते हैं (एक आदिम है और दूसरा ऑब्जेक्ट है)।


आदिम वस्तुएं बिल्कुल भी नहीं हैं। ऑपरेटर नहीं लौटेगा पुरातन के लिए।
typeof"object"

जब आप एक आदिम (किसी वस्तु के रूप में उपयोग करना) की संपत्ति तक पहुंचने का प्रयास करते हैं, तो जावास्क्रिप्ट भाषा इसे एक वस्तु पर बॉक्स करेगी, जो हर बार एक नई वस्तु बनाता है। यह विनिर्देशन में वर्णित है ।

यही कारण है कि आप प्राथमिकताओं पर गुण नहीं डाल सकते हैं:

var x = "a";
x.property = 2;
alert(x.property) //undefined

हर बार जब आप लिखते हैं x.property, तो एक अलग बॉक्सिंग Stringऑब्जेक्ट बनाया जाता है।


33
+1 typeof "foo"; // "string",typeof new String("foo"); // "object"
सैम्पसन

1
दिलचस्प है, मुझे लगा कि स्ट्रिंग्स जेएस में ऑब्जेक्ट थे।
कैमरन मार्टिन

1
@ सरफराज: लगभग सब कुछ। nullऔर के बारे में मत भूलना undefined

2
if( Object(a) !== a ) { //it's a primitive }
१५:५० में एसेलिजा

1
जावा में आदिम / नेट नहीं है
Marcelo De Zen

34

का उपयोग कर ===,

  • एक वस्तु अपने आप में किसी अन्य संदर्भ को छोड़कर कभी भी समान नहीं होती है।

  • एक आदिम की तुलना दूसरे प्राइमेट की तुलना में तब होती है जब उनका प्रकार और मूल्य समान हो।


3
new String("foo") === new String("foo")है false:-P
रॉकेट हज़मत

10

newशब्द एक आपराधिक यहाँ है ( हमेशा की तरह , मैं कह सकते हैं) ...

जब आप उपयोग करते हैं new, तो आप स्पष्ट रूप से ऑब्जेक्ट के साथ काम करने की इच्छा व्यक्त करते हैं । यह आपके लिए आश्चर्य की बात हो सकती है, लेकिन यह:

var x = new String('foo');
var y = new String('foo');
x === y; 

... आपको पराक्रम देगा false। यह सरल है: तुलना वस्तुओं की अंतर्वस्तु नहीं है, लेकिन वस्तुओं के संदर्भ हैं। और वे, ज़ाहिर है, समान नहीं हैं, क्योंकि दो अलग-अलग ऑब्जेक्ट बनाए गए थे।

आप शायद जो उपयोग करना चाहते हैं वह रूपांतरण है :

var x = String('foo');
var y = String('foo');
x === y;

... और जो आपको उम्मीद के मुताबिक trueपरिणाम देगा, इसलिए आप अपने बराबर के साथ खुश और समृद्ध हो सकते हैं foos। )


2
इसका उपयोग करने के बारे में त्वरित प्रश्न। आप 'नए' कीवर्ड के बिना स्ट्रिंग (एक निर्माता?) कह रहे हैं। इसका मतलब यह नहीं है कि आप स्ट्रिंग कंस्ट्रक्टर के भीतर निर्दिष्ट किसी भी गुण के साथ गुंजाइश को प्रदूषित करेंगे? या ऐसा इसलिए नहीं होता है क्योंकि कंस्ट्रक्टर मूल कोड है? दूसरे शब्दों में, मान लें कि स्ट्रिंग फ़ंक्शन में "this.a = 1;" है। - इसका मतलब है कि आपके फ़ंक्शन / ऑब्जेक्ट में अब एक संपत्ति होगी 1. 1.
माइकल बटलर

मुझे लगता है (लेकिन सुनिश्चित करने के लिए नहीं कह सकता) 'बॉक्सिंग कंस्ट्रक्टर' के प्रत्येक कार्य पहले इसके संदर्भ की जांच करता है - और अगर यह 'नया नहीं है' (यानी, एक प्रोटोटाइप ऑब्जेक्ट), तो तुरंत रूपांतरण विधि पर स्विच हो जाता है। स्ट्रिंग के मामले में toString(), उदाहरण के लिए, विधि होगी ।
बारिश।।


2

नोड से। REPL (यदि कमांड लाइन पर "नोड" स्थापित है):

> "foo" === (new String("foo")).valueOf()
true
> "foo" === new String("foo")
false
> typeof("foo")
'string'
> typeof(new String("foo"))
'object'
> typeof((new String("foo")).valueOf())
'string'
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.