2013-04-20 5 views
23

को समझना मैं समझने की कोशिश कर रहा हूं कि जावास्क्रिप्ट अपरिवर्तनीय चर का अर्थ क्या है। मैं क्या कर सकते हैं:जावास्क्रिप्ट अपरिवर्तनीय चर

var x = "astring"; 
x = "str"; 
console.log(x); //logs str` , then why it is immutable? 

केवल जवाब मैं (सीआई पता की छोटा सा से) में सोच सकते हैं कि वर एक्स मूल्य "astring" के साथ एक स्मृति ब्लॉक करने के लिए एक सूचक है, और 2 बयान के बाद यह मूल्य "str" ​​के साथ एक और ब्लॉक को इंगित करता है। क्या यह मामला है?

और एक बोनस प्रश्न: मैं जावास्क्रिप्ट के मूल्य प्रकारों से उलझन में था। हुड के नीचे सभी चर वस्तुएं हैं? यहां तक ​​कि संख्या और तार?

+1

डुप्लिकेट: http://stackoverflow.com/questions/3200211/what- करता है-अपरिवर्तनीय-माध्य – timss

+1

मैंने उस पोस्ट को देखा है। लेकिन मैं सिर्फ एक विधि नहीं बुलाता हूं। मैं एक नया मूल्य आवंटित करता हूं। क्या वही है? –

+1

एक नया मान असाइन करना ठीक है: एक नया मान असाइन करता है। आपने एक स्ट्रिंग को संशोधित नहीं किया है, आपने एक संदर्भ बदल दिया है। हां, वैरिएबल संदर्भ ऑब्जेक्ट्स: उदाहरण के लिए "हाय वहाँ" .split() 'या' टाइप 5''। –

उत्तर

37

मान अपरिवर्तनीय हैं; चर नहीं हैं; वे अपने (आदिम) मानों का संदर्भ रखते हैं।

तीन आदिम प्रकार स्ट्रिंग, संख्या और बूलियन इसी प्रकार जिसका उदाहरणों वस्तुओं रहे हैं: स्ट्रिंग, संख्या, बूलियन
उन्हें कभी-कभी wrapper types कहा जाता है।

निम्न मान primitive हैं:

  • स्ट्रिंग्स: "हैलो"
  • नंबर: 6, 3.14 (जावास्क्रिप्ट में सभी नंबरों को तैर ​​रहे हैं बिंदु)
  • Booleans: सच है, झूठी
  • अशक्त : आमतौर पर स्पष्ट रूप से
  • अपरिभाषित: आमतौर पर डिफ़ॉल्ट (स्वचालित रूप से असाइन किया गया) मान

अन्य सभी मूल्य प्राइमेटिव के लिए रैपर समेत ऑब्जेक्ट्स हैं।

तो:

  • वस्तुओं डिफ़ॉल्ट रूप से परिवर्तनशील
  • वस्तुओं है अद्वितीय पहचान कर रहे हैं और संदर्भ से तुलना की जाती है
  • चर वस्तुओं के लिए संदर्भ पकड़
  • प्रिमिटिव अपरिवर्तनीय
  • प्रिमिटिव से तुलना कर रहे हैं मूल्य, उनके पास व्यक्तिगत पहचान नहीं है

आपको The Secret Life of JavaScript Primitives एक अच्छा स्पष्टीकरण मिल सकता है।

इसके अलावा, ईएस 6 में एक नया const कीवर्ड है, जो केवल पढ़ने के लिए नामित स्थिर बनाता है जो असाइनमेंट के माध्यम से मूल्य नहीं बदल सकता है या स्क्रिप्ट चल रहा है, फिर से घोषित किया जा सकता है।

आशा है कि इससे मदद मिलती है!

+0

धन्यवाद यह मदद करता है। लेकिन मुझे नहीं पता कि कौन सी अनूठी पहचान है .. साथ ही, क्या मैं इन रैपरों से प्राइमेटिव कैसे जुड़े हैं, इसके बारे में और अधिक विश्लेषणात्मक जानकारी प्राप्त कर सकता हूं? बस मुझे अजीब लग रहा है कि मैं प्राइमेटिव्स (जैसे aString.length) पर एक विधि कॉल कर सकता हूं। –

+1

*** रैपर *** विधि 'लंबाई' है। मेरे उत्तर की दूसरी पंक्ति में आवरण नोट करें। यह [लिंक: जावास्क्रिप्ट प्राइमेटिव्स का गुप्त जीवन] (http://javascriptweblog.wordpress.com/2010/09/27/the-secret-life-of-javascript-primitives/) बहुत मदद कर सकता है! – GitaarLAB

+0

तो, यदि मैंने इसे सही ढंग से समझा है, तो सी के विपरीत, जावास्क्रिप्ट में, यदि आपके पास संदर्भित स्मृति स्थान है, तो var x = 1; सामग्री 0000000000000001 होने के बाद ** "अपरिवर्तनीयता" ** का तात्पर्य है कि हम 0000000000000011 कहने के लिए मेमोरी लेकोशन की सामग्री को नहीं बदल सकते हैं। यदि ऐसा है तो, यदि मैं var x = 1 लिखता हूं; एक्स = 2; हर बार जावास्क्रिप्ट मुझे एक नया मेमोरी लोकेशन और कचरा प्रदान करेगा-पुराने अप्रत्याशित एक को इकट्ठा करेगा? –

5

आप सही हैं। स्ट्रिंग्स (और संख्याएं) जावा स्क्रिप्ट (और कई अन्य भाषाओं) में अपरिवर्तनीय हैं। चर उनके संदर्भ हैं। जब आप "चर के मान को बदलते हैं" तो आप स्ट्रिंग (या जो कुछ भी) बदल रहे हैं, वेरिएबल संदर्भ, मान स्वयं नहीं।

+0

मुझे लगता है कि मैं समझना शुरू कर रहा हूं, धन्यवाद।क्या आप जानते हैं कि पहले मूल्य के साथ क्या होता है (मेरे उदाहरण में "अस्थिर")? कचरा कलेक्टर पास होने तक यह स्मृति में मौजूद है? –

14

सबसे पहले, सी में "एक स्ट्रिंग अंतिम elem = '\ 0' वाले वर्णों की एक सरणी है। वे उत्परिवर्तनीय हैं।
आप घोषित करने और इस तरह सी में एक स्ट्रिंग को प्रारंभ करते हैं:

char str[] = "Foo"; 

क्या आप मूल रूप से कर रहे हैं 4 बाइट आरक्षित है (शायद 8 बिट बाइट, यह शायद कोई आपत्ति नहीं है अगर यह आपको दर्द होता है)। शब्द str इस सरणी के पहले elem के लिए एक सूचक के रूप में कार्य करता है। इसलिए, यदि आप ऐसा करते हैं:

str[0] or *(str) = 'G' 

तो यह नई सरणी बनाने के बजाय उस पते पर मान को बदल देगा। आप स्ट्र के पते को प्रिंट करके इसे सत्यापित कर सकते हैं। दोनों मामलों में यह वही होगा।

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

var str1 = "foo"; 
var str2 = "foo"; 
str1 === str2; => true 

स्ट्रिंग के प्रारंभ एक बफर के लिए पूछता है "foo" फिट करने के लिए और यह करने के नाम str1 बांधता है। उन्हें अपरिवर्तनीय बनाता है कि आप उस बफर को नहीं बदल सकते हैं। तो, आप यह कर सकते हैं नहीं:

str1[0] = 'G' 

इस आदेश निष्पादित कोई चेतावनी या गैर कठोर मोड में त्रुटि उत्पन्न करेगा लेकिन, यह str1 नहीं बदलेगा। आप

console.log(str1) => "foo" 

द्वारा यह सत्यापित कर सकते हैं लेकिन अगर आप इस तरह कार्य करें:

str1 = "goo" 

क्या आप वास्तव में कर रहे हैं कि आप एक नया बफर के लिए पूछ रहे हैं "goo" फिट और करने के लिए पहचानकर्ता str1 बाध्य करने के लिए है यह। उस पुराने बफर में कोई बदलाव नहीं है जिसमें "foo" है।

तो, "foo" के साथ क्या होता है?

जावा स्क्रिप्ट में एक स्वचालित कचरा कलेक्टर है। जब यह स्मृति के कुछ हिस्से को देखता है जिसे किसी भी पहचानकर्ता द्वारा संदर्भित नहीं किया जा सकता है या ... तो यह उस स्मृति को मुक्त मानता है।

संख्या, बूलियन के समान होता है। अब, रैपर ऑब्जेक्ट्स के बारे में! जब भी आप इस तरह स्ट्रिंग पर एक संपत्ति तक पहुँचने का प्रयास:

str1.length; 

क्या जावास्क्रिप्ट यह स्ट्रिंग वर्ग का उपयोग कर एक नई वस्तु बनाता है और स्ट्रिंग पर विधियां प्रारंभ करता है। जैसे ही फ़ंक्शन कॉल लौटाता है, ऑब्जेक्ट नष्ट हो जाता है। नीचे कोड इसे आगे बताते हैं:

var str = "nature"; 
str.does = "nurtures"; //defining a new property; 
console.log(str.does) => undefined 

क्योंकि वस्तु को नष्ट कर दिया गया है। इसे आजमाएं!

var str = new String("Nature"); 
str.does = "nurtures"; 
console.log(str) => ?? 

इस str वास्तव में एक वस्तु है ...

निष्कर्ष: सी में, एक ही दायरे में चर नाम सूचक के रूप में कार्य करता है। तो, int, float, स्ट्रिंग सभी mutable हैं।लेकिन जावा स्क्रिप्ट में एक आदिम प्रकार चर नाम मूल्य के रूप में कार्य करता है नहीं संदर्भ के रूप में

संदर्भ: सी ++ प्राइमर प्लस, जावा स्क्रिप्ट निश्चित गाइड, सी स्टीफन कोचन द्वारा

+0

"स्ट्रिंग पर सभी ऑपरेशन संदर्भ के बजाय मूल्य द्वारा किए जाते हैं" मैं उलझन में हूं। एक स्ट्रिंग वास्तव में एक बफर का संदर्भ नहीं है? –

+0

@LeCurious इन सी यदि आप इस char str [] = "foo" पसंद करते हैं। फिर str बफर को एक संदर्भ (सूचक) होगा। आप इस संदर्भ का उपयोग कर उस बफर में परिवर्तन कर सकते हैं। लेकिन, जावास्क्रिप्ट में यदि आप यह var str = "hi" करते हैं। फिर str एक पठन-केवल पहचानकर्ता है जिसका प्रयोग बफर तक पहुंचने के लिए किया जाता है जहां हाय संग्रहीत किया जाता है। – aMother

+1

तो कुछ अर्थ में केवल पढ़ने-योग्य बफर का संदर्भ है? –

0

मुझे लगता है कि कई नए प्रोग्रामर का मानना ​​है कि इसका मतलब यह करने के लिए अचल स्थिति आदिम मूल्य पुन: असाइनमेंट द्वारा बदला नहीं जा सकता है।

var str = "testing"; 
 
var str = "testing,testing"; 
 
console.log(str); // testing, testing

var fruits = ["apple", "banana", "orange"]; 
 

 
fruits[0] = "mango"; 
 

 
console.log(fruits); //["mango", "banana", "orange"]

दोनों परिवर्तनशील और अपरिवर्तनीय प्रकार के साथ जुड़े मूल्यों पुनर्निर्धारण के माध्यम से बदला जा सकता है के रूप में तार और सरणियों के साथ ऊपर के उदाहरण दिखाते हैं। लेकिन फिर, इन डेटा प्रकारों में कार्य (विधियों) से जुड़े होते हैं जिनका उपयोग प्रत्येक डेटा प्रकार से संबंधित मानों में हेरफेर करने के लिए किया जाता है। यह वह जगह है जहां उत्परिवर्तन/अपरिवर्तनीयता देखी जाती है। चूंकि सरणी उत्परिवर्तनीय हैं, इसलिए किसी सरणी विधि द्वारा कोई हेरफेर सीधे सरणी को प्रभावित करता है। उदाहरण के लिए,

var fruits = ["mango","banana", "orange"]; 
 
fruits.pop(); 
 
console.log(fruits) //["mango", "banana"] 
 

 

 
The array.pop() method deleted "orange" from the original fruits array. 
 
But with strings for example, 
 

 

 
var name = "Donald Trump"; 
 
name.replace("Donald", "President"); 
 
console.log(name)//Donald Trump 
 

 
the original string remains intact!

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

var name = "Donald Trump"; 
 
var newName = name.replace("Donald", "President"); 
 
console.log(newName);//President Trump

संबंधित मुद्दे