चर असाइनमेंट जावास्क्रिप्ट में कैसे काम करता है?


98

इसलिए मैं दूसरे दिन के आसपास खेल रहा था कि वास्तव में यह देखने के लिए कि जावास्क्रिप्ट में बड़े पैमाने पर काम कैसे होता है।

पहले मैंने कंसोल में इस उदाहरण की कोशिश की:

a = b = {};
a.foo = 'bar';
console.log(b.foo);

परिणाम एक चेतावनी में "बार" प्रदर्शित किया जा रहा था। यह काफी उचित है, aऔर bवास्तव में सिर्फ एक ही वस्तु के लिए उपनाम हैं। फिर मैंने सोचा, मैं इस उदाहरण को कैसे सरल बना सकता हूं।

a = b = 'foo';
a = 'bar';
console.log(b);

यह बहुत ज्यादा एक ही बात है, है ना? खैर इस बार, यह fooनहीं है barक्योंकि मैं पहले उदाहरण के व्यवहार से उम्मीद करूंगा।

क्यों होता है ऐसा?

NB इस उदाहरण को निम्न कोड के साथ और भी सरल बनाया जा सकता है:

a = {};
b = a;
a.foo = 'bar';
console.log(b.foo);

a = 'foo';
b = a;
a = 'bar';
console.log(b);

(मुझे संदेह है कि जावास्क्रिप्ट आदिमों को स्ट्रिंग्स और पूर्णांकों को अलग-अलग करने के लिए व्यवहार करता है। हैश एक पॉइंटर लौटाते हैं जबकि "कोर" प्राइमेटिव खुद की एक प्रति वापस करते हैं)


यहाँ असाइनमेंट को समझाते हुए: syntaxsuccess.com/viewarticle/…
TGH

जवाबों:


114

पहले उदाहरण में, आप किसी मौजूदा ऑब्जेक्ट की प्रॉपर्टी सेट कर रहे हैं। दूसरे उदाहरण में, आप एक बिलकुल नई वस्तु प्रदान कर रहे हैं।

a = b = {};

aऔर bअब उसी वस्तु की ओर संकेत करते हैं। तो जब आप करते हैं:

a.foo = 'bar';

यह सेट b.fooके बाद से अच्छी तरह से aऔर bबिंदु एक ही वस्तु है।

तथापि!

यदि आप इसके बजाय ऐसा करते हैं:

a = 'bar';

आप कह रहे हैं कि aअब एक अलग वस्तु की ओर इशारा करते हैं। इससे aपहले क्या इंगित किया गया उस पर कोई प्रभाव नहीं है ।

जावास्क्रिप्ट में, एक चर को निर्दिष्ट करना और एक संपत्ति निर्दिष्ट करना 2 अलग-अलग संचालन हैं। ऑब्जेक्ट के लिए पॉइंटर्स के रूप में वेरिएबल्स के बारे में सोचना सबसे अच्छा है, और जब आप सीधे वेरिएबल को असाइन करते हैं, तो आप किसी ऑब्जेक्ट को मॉडिफाई नहीं कर रहे हैं, केवल अपने वेरिएबल को एक अलग ऑब्जेक्ट में रिपीट कर रहे हैं।

लेकिन एक संपत्ति असाइन करना, जैसे a.foo, उस ऑब्जेक्ट को संशोधित करेगा जो aइंगित करता है। यह, निश्चित रूप से, इस ऑब्जेक्ट को इंगित करने वाले अन्य सभी संदर्भों को भी संशोधित करता है क्योंकि वे सभी एक ही ऑब्जेक्ट को इंगित करते हैं।


3
"आप कह रहे हैं कि अब एक अलग वस्तु के लिए एक अंक।" नहीं, ऑब्जेक्ट शब्द का उपयोग न करें। एक स्ट्रिंग जावास्क्रिप्ट में एक वस्तु नहीं है।
नोसरेडना

9
हो सकता है कि तार तकनीकी रूप से जावास्क्रिप्ट प्रकार के "ऑब्जेक्ट" नहीं हैं, लेकिन उन्हें OO अर्थों में वस्तुओं के बारे में सोचा जा सकता है।
एलेक्स वेन

2
@Squeegy: स्ट्रिंग्स आदिम हैं, ऑब्जेक्ट नहीं: आप स्ट्रिंग्स के लिए मनमाने गुण नहीं दे सकते! वे केवल जावा
क्रिस्टोफ

11
लेकिन तार के तरीके और गुण हैं, और स्ट्रिंग के प्रोटोटाइप को निश्चित रूप से संशोधित किया जा सकता है। वे निश्चित रूप से वस्तुओं की तरह कार्य करते हैं।
कैमरून मार्टिन

9
@ddlshack: जैसा कि क्रिस्टोफ़ ने समझाया, यह ऑटोबॉक्सिंग के कारण है। यदि आप एक स्ट्रिंग को परिभाषित करने वाले थे var foo = new String('foo');, तो वह एक स्ट्रिंग ऑब्जेक्ट typeofहोगी (और इस बात की पुष्टि करेगा)। लेकिन अगर आप इसे एक स्ट्रिंग शाब्दिक के माध्यम से घोषित करते हैं, तो वे स्ट्रिंग प्राइमेटिव हैं। देखें: developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…
Lèse majesté

26

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

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

जावास्क्रिप्ट में, मूल रूप से दो अलग-अलग प्रकार के मूल्य हैं: आदिम और वस्तुएं (और 'हैश' जैसी कोई चीज नहीं है)।

स्ट्रिंग्स, संख्याओं और बूलियन के साथ-साथ nullऔर undefinedकर रहे हैं पुरातन, वस्तुओं सब कुछ गुण होते हैं सकता है जो कर रहे हैं। यहां तक ​​कि एरेज़ और फ़ंक्शंस नियमित ऑब्जेक्ट हैं और इसलिए मनमाने गुण धारण कर सकते हैं। वे केवल आंतरिक [[कक्षा]] संपत्ति में भिन्न होते हैं (अतिरिक्त कार्यों में एक संपत्ति होती है जिसे [[कॉल]] और [[निर्माण]] कहा जाता है, लेकिन हे, यह विवरण है)।

कारण यह है कि आदिम मूल्य वस्तुओं की तरह व्यवहार कर सकते हैं क्योंकि ऑटोबॉक्सिंग की वजह से है, लेकिन आदिम स्वयं किसी भी गुण को धारण नहीं कर सकते हैं।

यहाँ एक उदाहरण है:

var a = 'quux';
a.foo = 'bar';
document.writeln(a.foo);

यह आउटपुट करेगा undefined: aएक आदिम मूल्य रखता है, जो संपत्ति को असाइन करते समय किसी वस्तु को बढ़ावा देता है foo। लेकिन यह नई वस्तु तुरंत खारिज हो जाती है, इसलिए मूल्य fooखो जाता है।

इसके बारे में इस तरह से सोचें:

var a = 'quux';
new String(a).foo = 'bar'; // we never save this new object anywhere!
document.writeln(new String(a).foo); // a completly new object gets created

मोज़िला फाउंडेशन के पृष्ठ 'जावास्क्रिप्ट का पुनः परिचय (जेएस ट्यूटोरियल)' जावास्क्रिप्ट वस्तुओं का वर्णन करता है "नाम-मूल्य जोड़े के सरल संग्रह के रूप में। इस तरह, वे ... के समान हैं", फिर शब्दकोशों की सूची के साथ अनुसरण करता है, हैश। , हैश टेबल, और विभिन्न प्रोग्रामिंग भाषाओं से हैश मैप। एक ही पृष्ठ हैश टेबल लुकअप के रूप में ऑब्जेक्ट प्रॉपर्टी संदर्भ का वर्णन करता है। तो वस्तुएं एक 'हैश' टेबल की तरह सब कुछ हैं। यह अन्य उपयोगी जानकारी को स्पष्ट नहीं करता है, लेकिन क्रिस लॉयड का मूल लक्षण वर्णन गलत नहीं था।
सी पर्किंस

2

आप कमोबेश सही हैं सिवाय इसके कि आप जिस चीज को "हैश" कह रहे हैं वह वास्तव में किसी वस्तु के लिए केवल शॉर्टहैंड सिंटैक्स है।

पहले उदाहरण में, और बी दोनों एक ही वस्तु को संदर्भित करते हैं। दूसरे उदाहरण में, आप बदलना एक कुछ और का उल्लेख करने के।


तो वस्तु के लिए दोहरा मापदंड क्यों?
क्रिस लॉयड

इसका दोहरा मापदंड नहीं है। पहले उदाहरण में, a और b अभी भी एक ही ऑब्जेक्ट को संदर्भित करते हैं, आप बस उस ऑब्जेक्ट की एक संपत्ति को संशोधित कर रहे हैं। दूसरे उदाहरण में, आप किसी भिन्न ऑब्जेक्ट पर इंगित कर रहे हैं।
केविन

1
नहीं, अंतर यह है कि दूसरे मामले में, आप एक वस्तु नहीं, एक स्ट्रिंग के साथ काम कर रहे हैं।
नोसरेडना

1
स्पष्ट होना: इसका स्वयं की प्रति लौटाने वाले तार से कोई लेना-देना नहीं है। कारण दो कोड स्निपेट्स अलग हैं केविन के दूसरे पैराग्राफ में है (स्क्वी के उत्तर में अधिक पूरी तरह से समझाया गया है)।
चक

इससे कोई फर्क नहीं पड़ता कि आपके पास चर में कोई स्ट्रिंग या ऑब्जेक्ट है। आप एक नया, भिन्न मान निर्दिष्ट करते हैं और फिर चर में नया, अलग मूल्य होता है।
sth

2

यहाँ जवाब का मेरा संस्करण है:

obj = {a:"hello",b:"goodbye"}
x = obj
x.a = "bonjour"

// now obj.a is equal to "bonjour"
// because x has the same reference in memory as obj
// but if I write:
x = {}
x.a = obj.a
x.b = obj.b
x.a = "bonjour"

// now x = {a:"bonjour", b:"goodbye"} and obj = {a:"hello", b:"goodbye"}
// because x points to another place in the memory

0

आप एक नई स्ट्रिंग ऑब्जेक्ट को इंगित करने के लिए सेट कर रहे हैं, जबकि b पुराने स्ट्रिंग ऑब्जेक्ट की ओर इशारा करता है।


0

पहले मामले में आप चर में निहित वस्तु की कुछ संपत्ति को बदलते हैं, दूसरे मामले में आप चर को एक नया मूल्य प्रदान करते हैं। यह मौलिक रूप से अलग चीजें हैं। चर aऔर bकिसी भी तरह से जादुई रूप से पहले असाइनमेंट द्वारा लिंक नहीं किए गए हैं, वे बस एक ही ऑब्जेक्ट होते हैं। दूसरे उदाहरण में भी यही है, जब तक आप bवैरिएबल को नया मान नहीं देते ।


0

अंतर सरल प्रकार और वस्तुओं के बीच है।

जो कुछ भी वस्तु (एक सरणी या एक समारोह की तरह) संदर्भ द्वारा पारित किया जाता है।

जो कुछ भी एक सरल प्रकार (जैसे एक स्ट्रिंग या एक संख्या) की प्रतिलिपि बनाई जाती है।

मेरे पास हमेशा एक copyArray फ़ंक्शन काम होता है इसलिए मुझे यकीन है कि मैं समान सरणी में उपनामों का एक गुच्छा नहीं बना रहा हूं।


अंतर कई परिदृश्यों में ध्यान देने योग्य नहीं है, लेकिन जावास्क्रिप्ट वास्तव में संदर्भ द्वारा पारित या असाइन नहीं करता है। यह संदर्भ मूल्यों को कॉपी करता है।
जुआन पाब्लो कैलिफानो

इन लोगों ने पहले से ही इसे समझाते हुए एक अच्छा काम किया है, इसलिए मैं केवल लिंक पेस्ट करूंगा: stackoverflow.com/questions/40480/is-java-pass-by-reference (मैं जावा को संदर्भित करता हूं, लेकिन पास करने और असाइन करने के लिए शब्दार्थ मान / संदर्भ जावास्क्रिप्ट में जैसे ही हैं)
जुआन पाब्लो कैलिफानो

1
वास्तव में यह उत्तर गलत है, सब कुछ जावास्क्रिप्ट में मूल्य द्वारा पारित किया गया है। एमडीएन से, "एक फ़ंक्शन कॉल के पैरामीटर फ़ंक्शन के तर्क हैं। मानों को फ़ंक्शन द्वारा तर्क पारित किए जाते हैं। यदि फ़ंक्शन किसी तर्क के मान को बदलता है, तो यह परिवर्तन विश्व स्तर पर या कॉलिंग फ़ंक्शन में प्रतिबिंबित नहीं होता है। हालांकि, ऑब्जेक्ट संदर्भ हैं। मान, भी, और वे विशेष हैं: यदि फ़ंक्शन संदर्भित ऑब्जेक्ट के गुणों को बदलता है, तो यह फ़ंक्शन फ़ंक्शन के बाहर दिखाई देता है। " developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
bittersweetryan

आदिम अपरिवर्तनीय वस्तुओं की तरह व्यवहार करते हैं ( बिल्कुल उनके जैसे सख्त मोड में)। यह उत्तर सही नहीं है।
Ry-
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.