2012-06-08 21 views
97

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

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

झूठा है, और इस के साथ एक ही है:

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

बेशक:

f == g; // true 

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

+4

हो सकता है कि क्योंकि 'foo' शुद्ध स्ट्रिंग और' नई स्ट्रिंग ("foo" है) 'है ऑब्जेक्ट स्ट्रिंग –

+0

पृष्ठभूमि: http://stackoverflow.com/questions/1646698/what-is-the-new-keyword-in-javascript –

+6

यह अनुशंसा की जाती है कि 'नई स्ट्रिंग' (पूरी तरह से व्यर्थ) के साथ स्ट्रिंग न बनाएं '==' – Esailija

उत्तर

124

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

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

=== ऑपरेटर behaves differently on primitives and objects
प्राइमेटिव्स (उसी प्रकार के) की तुलना करते समय, === सही होगा यदि दोनों के पास समान मूल्य है।

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

आपके मामले में, === झूठी वापसी करता है क्योंकि ऑपरेंड विभिन्न प्रकार के होते हैं (एक आदिम है और दूसरा एक वस्तु है)।


Primitives ऑब्जेक्ट्स बिल्कुल नहीं हैं।
typeof ऑपरेटर प्राइमेटिव्स के लिए "object" वापस नहीं करेगा।

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

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

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

हर बार जब आप लिखना x.property, एक अलग बॉक्सिंग String वस्तु बन जाता है।

+32

+1 'typeof "foo"; // "स्ट्रिंग" ', 'टाइपिंग नई स्ट्रिंग (" foo "); // "ऑब्जेक्ट" ' – Sampson

+1

दिलचस्प, मैंने सोचा कि तार जेएस में ऑब्जेक्ट्स थे। – ddlshack

+0

@ddlshack: यदि आप इसके उदाहरण बनाते हैं तो सबकुछ एक ऑब्जेक्ट भी स्ट्रिंग हो सकता है। – Sarfraz

4

foo शुद्ध स्ट्रिंग है और new String("foo") वस्तु स्ट्रिंग

34

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

  • एक वस्तु ही एक और संदर्भ के अलावा कुछ करने के लिए कभी नहीं बराबर है।

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

+3

'नया स्ट्रिंग ("foo") === नया स्ट्रिंग ("foo") '' false' है :-P –

+11

@ रॉकेट: बिल्कुल मेरी बात। –

+5

@ रॉकेट: चूंकि वे दो अलग-अलग संदर्भ हैं ... –

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. –

+0

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

2

Node.js आरईपीएल से (कमांड लाइन पर "नोड" यदि स्थापित):

> "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'
संबंधित मुद्दे