TLDR
प्रकार का ज़बरदस्ती, या अंतर्निहित प्रकार रूपांतरण, कमजोर टाइपिंग को सक्षम करता है और पूरे जावास्क्रिप्ट में उपयोग किया जाता है। अधिकांश ऑपरेटर (सख्त समानता ऑपरेटरों के उल्लेखनीय अपवाद के साथ ) ===और !==, और मूल्य की जांच के संचालन (जैसे। if(value)...), उन लोगों को दिए गए मानों को एकरूप कर देंगे, यदि उन मानों के प्रकार तुरंत संचालन के अनुकूल नहीं हैं।
किसी मूल्य का ज़बरदस्त इस्तेमाल करने वाला सटीक तंत्र उस मूल्यांकन पर निर्भर करता है जिसका मूल्यांकन किया जा रहा है। प्रश्न में, अतिरिक्त ऑपरेटर का उपयोग किया जा रहा है।
इसके अलावा ऑपरेटर पहले यह सुनिश्चित करेगा कि दोनों ऑपरेंड प्राइमेटिव हैं, जो इस मामले में, कॉलिंग valueOfमेथड शामिल है । toStringविधि इस उदाहरण में नहीं बुलाया क्योंकि ओवरराइड है valueOfवस्तु पर विधि xएक आदिम मान देता है।
फिर, क्योंकि प्रश्न में एक ऑपरेंड एक स्ट्रिंग है, दोनों ऑपरेंड को स्ट्रिंग्स में परिवर्तित किया जाता है। यह प्रक्रिया अमूर्त, आंतरिक संचालन ToString(नोट: पूंजीकृत) का उपयोग करती है, और toStringऑब्जेक्ट पर विधि (या इसके प्रोटोटाइप श्रृंखला) से अलग है।
अंत में, परिणामी तार समवर्ती होते हैं।
विवरण
जावास्क्रिप्ट में हर भाषा प्रकार के अनुरूप हर कंस्ट्रक्टर फंक्शन ऑब्जेक्ट के प्रोटोटाइप पर (जैसे। संख्या, बिगआईंट, स्ट्रिंग, बुलियन, सिंबल और ऑब्जेक्ट), दो तरीके हैं: valueOfऔरtoString ।
इसका उद्देश्य valueOfकिसी वस्तु के साथ जुड़े हुए आदिम मूल्य (यदि यह एक है) को पुनः प्राप्त करना है। यदि किसी वस्तु में अंतर्निहित आदिम मूल्य नहीं है, तो वस्तु बस वापस आ जाती है।
यदि valueOfएक आदिम के खिलाफ आह्वान किया जाता है, तो आदिम सामान्य तरीके से ऑटो-बॉक्स होता है, और अंतर्निहित आदिम मूल्य वापस आ जाता है। ध्यान दें कि तार के लिए, अंतर्निहित आदिम मूल्य (यानी द्वारा लौटाए गए मूल्य valueOf) स्ट्रिंग का प्रतिनिधित्व है।
निम्न कोड से पता चलता है कि valueOfविधि एक आवरण वस्तु से अंतर्निहित आदिम मूल्य लौटाती है, और यह दिखाती है कि कैसे असंबद्ध वस्तु उदाहरण जो कि आदिम के अनुरूप नहीं हैं, वापस लौटने के लिए कोई आदिम मूल्य नहीं है, इसलिए वे बस खुद को वापस करते हैं।
console.log(typeof new Boolean(true)) // 'object'
console.log(typeof new Boolean(true).valueOf()) // 'boolean'
console.log(({}).valueOf()) // {} (no primitive value to return)
के प्रयोजन के toString, दूसरे हाथ पर, एक वस्तु के एक स्ट्रिंग प्रतिनिधित्व वापसी है।
उदाहरण के लिए:
console.log({}.toString()) // '[object Object]'
console.log(new Number(1).toString()) // '1'
अधिकांश परिचालनों के लिए, जावास्क्रिप्ट चुपचाप एक या एक से अधिक ऑपरेंड (ओं) को आवश्यक प्रकार में बदलने का प्रयास करेगा। यह व्यवहार जावास्क्रिप्ट का उपयोग करने के लिए आसान बनाने के लिए चुना गया था। जावास्क्रिप्ट में शुरू में अपवाद नहीं थे , और इस डिजाइन निर्णय में भी भूमिका हो सकती है। इस प्रकार के निहितार्थ रूपांतरण को प्रकार का जोर कहा जाता है, और यह जावास्क्रिप्ट की ढीली (कमजोर) प्रकार प्रणाली का आधार है। इस व्यवहार के पीछे के जटिल नियमों का उद्देश्य भाषा में टाइपकास्टिंग की जटिलता को अपने आप में और अपने कोड से बाहर ले जाना है।
ज़बरदस्त प्रक्रिया के दौरान, रूपांतरण के दो तरीके हो सकते हैं:
- एक वस्तु का एक आदिम में रूपांतरण (जिसमें स्वयं एक प्रकार का रूपांतरण शामिल हो सकता है), और
- एक विशेष प्रकार का उदाहरण के लिए सीधी रूपांतरण, आदिम प्रकार से एक के एक निर्माता समारोह वस्तु का उपयोग कर (यानी।
Number(), Boolean(), String()आदि)
एक आदिम में रूपांतरण
गैर-आदिम प्रकारों को संचालन के लिए प्राइमिटिव में परिवर्तित करने का प्रयास करते समय, अमूर्त ऑपरेशन ToPrimitiveको 'संख्या', या 'स्ट्रिंग' के वैकल्पिक "संकेत" के साथ कहा जाता है। यदि संकेत छोड़ा गया है, तो डिफ़ॉल्ट संकेत 'संख्या' है (जब तक कि @@toPrimitiveविधि को ओवरराइड नहीं किया गया है)। यदि संकेत 'स्ट्रिंग' है, तो toStringपहले की कोशिश की जाती है, और valueOfअगर toStringएक आदिम वापस नहीं आया तो दूसरा । एल्स, इसके विपरीत। संकेत रूपांतरण का अनुरोध करने वाले ऑपरेशन पर निर्भर करता है।
इसके अलावा ऑपरेटर कोई संकेत नहीं देता है, इसलिए valueOfपहले प्रयास किया जाता है। घटाव ऑपरेटर 'संख्या' के संकेत की आपूर्ति करता है, इसलिए valueOfपहले प्रयास किया जाता है। केवल उन स्थितियों में मैं पा सकता हूं जिनमें संकेत 'स्ट्रिंग' हैं:
Object#toString
- अमूर्त ऑपरेशन
ToPropertyKey, जो एक तर्क को एक मूल्य में परिवर्तित करता है जिसे संपत्ति कुंजी के रूप में उपयोग किया जा सकता है
प्रत्यक्ष प्रकार रूपांतरण
प्रत्येक ऑपरेटर के पास अपना ऑपरेशन पूरा करने के अपने नियम हैं। प्रत्येक ऑपरेटर ToPrimitiveएक आदिम है यह सुनिश्चित करने के लिए सबसे पहले ऑपरेटर का उपयोग करेगा ; फिर, यदि कोई ऑपरेंड एक स्ट्रिंग है, तो यह ToStringस्ट्रिंग के कॉन्सेप्टेशन व्यवहार को प्रदान करने के लिए जानबूझकर प्रत्येक ऑपरेंड पर अमूर्त ऑपरेशन को लागू करेगा । यदि, ToPrimitiveचरण के बाद , दोनों ऑपरेंड स्ट्रिंग्स नहीं हैं, तो अंकगणित जोड़ दिया जाता है।
इसके अलावा, घटाव ऑपरेटर में अतिभारित व्यवहार नहीं होता है, और इसलिए toNumericप्रत्येक ऑपरेंड पर आह्वान करेगा जो पहले उन्हें उपयोग करने वाली प्राथमिकताओं में परिवर्तित कर देगा ToPrimitive।
इसलिए:
1 + 1 // 2
'1' + 1 // '11' Both already primitives, RHS converted to string, '1' + '1', '11'
1 + [2] // '12' [2].valueOf() returns an object, so `toString` fallback is used, 1 + String([2]), '1' + '2', 12
1 + {} // '1[object Object]' {}.valueOf() is not a primitive, so toString fallback used, String(1) + String({}), '1' + '[object Object]', '1[object Object]'
2 - {} // NaN {}.valueOf() is not a primitive, so toString fallback used => 2 - Number('[object Object]'), NaN
+'a' // NaN `ToPrimitive` passed 'number' hint), Number('a'), NaN
+'' // 0 `ToPrimitive` passed 'number' hint), Number(''), 0
+'-1' // -1 `ToPrimitive` passed 'number' hint), Number('-1'), -1
+{} // NaN `ToPrimitive` passed 'number' hint', `valueOf` returns an object, so falls back to `toString`, Number('[Object object]'), NaN
1 + 'a' // '1a' Both are primitives, one is a string, String(1) + 'a'
1 + {} // '1[object Object]' One primitive, one object, `ToPrimitive` passed no hint, meaning conversion to string will occur, one of the operands is now a string, String(1) + String({}), `1[object Object]`
[] + [] // '' Two objects, `ToPrimitive` passed no hint, String([]) + String([]), '' (empty string)
1 - 'a' // NaN Both are primitives, one is a string, `ToPrimitive` passed 'number' hint, 1-Number('a'), 1-NaN, NaN
1 - {} // NaN One primitive, one is an object, `ToPrimitive` passed 'number' hint, `valueOf` returns object, so falls back to `toString`, 1-Number([object Object]), 1-NaN, NaN
[] - [] // 0 Two objects, `ToPrimitive` passed 'number' hint => `valueOf` returns array instance, so falls back to `toString`, Number('')-Number(''), 0-0, 0
ध्यान दें कि Dateआंतरिक वस्तु अद्वितीय है, इसमें डिफ़ॉल्ट @@toPrimitiveविधि को ओवरराइड करने के लिए एकमात्र आंतरिक है , जिसमें डिफ़ॉल्ट संकेत को 'स्ट्रिंग' ('संख्या' के बजाय) माना जाता है। ऐसा करने का कारण, Dateप्रोग्रामर की सुविधा के लिए, उदाहरणों को उनके संख्यात्मक मान के बजाय डिफ़ॉल्ट रूप से पठनीय स्ट्रिंग्स में अनुवाद करना है। आप @@toPrimitiveअपनी खुद की वस्तुओं का उपयोग करके ओवरराइड कर सकते हैं Symbol.toPrimitive।
निम्न ग्रिड सार समानता ऑपरेटर ( ==) ( स्रोत ) के लिए ज़बरदस्ती परिणाम दिखाता है :

देखें भी ।
window.console.log (x);याalert (x);?