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


101

मुझे पता है कि ES6 अभी तक मानकीकृत नहीं है, लेकिन बहुत सारे ब्राउज़र वर्तमान const में JS में कीवर्ड का समर्थन करते हैं

कल्पना में, यह लिखा है कि:

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

और जब मैं ऐसा कुछ करता हूं:

const xxx = 6;
xxx = 999;
xxx++;
const yyy = [];
yyy = 'string';
yyy = [15, 'a'];

मैं देखता हूं कि सब कुछ ठीक xxxहै 6और अभी भी yyyहै []

लेकिन अगर मैं करता हूं yyy.push(6); yyy.push(1);, तो मेरे निरंतर सरणी को बदल दिया गया है। अभी यह है [6, 1]और वैसे मैं अभी भी इसे बदल नहीं सकता हूं yyy = 1;

मैं यह एक बग, या मैं कुछ याद कर रहा हूँ? मैंने इसे नवीनतम क्रोम और FF29 में आज़माया


1
क्या आप सिर्फ एक क्लास बना सकते हैं, वेरिएबल घोषित कर सकते हैं और क्लास के अंदर उसकी वैल्यू असाइन कर सकते हैं। फिर, उस वेरिएबल के लिए GETTER बनाएं; और एक सेटर को लागू न करें। इसे एक निरंतरता को लागू करना चाहिए ...
एंड्रयू

8
@ और धन्यवाद, लेकिन मैं यह नहीं पूछ रहा हूं कि मैं यह कैसे कर सकता हूं। मैं उत्सुक हूं कि कॉन्स्ट कीवर्ड इस तरह क्यों व्यवहार करता है।
साल्वाडोर डाली

जवाबों:


172

प्रलेखन में कहा गया है:

... निरंतर पुन: असाइनमेंट के माध्यम से नहीं बदल सकता है
... निरंतर को फिर से घोषित नहीं किया जा सकता है

जब आप किसी ऐसे सरणी या ऑब्जेक्ट को जोड़ रहे हैं जिसे आप पुन: असाइन नहीं कर रहे हैं या निरंतर को पुनः घोषित कर रहे हैं, तो यह पहले से ही घोषित और असाइन किया गया है, आप केवल "सूची" में जोड़ रहे हैं जो कि निरंतर बिंदु है।

तो यह ठीक काम करता है:

const x = {};

x.foo = 'bar';

console.log(x); // {foo : 'bar'}

x.foo = 'bar2';

console.log(x); // {foo : 'bar2'}  

और इस:

const y = [];

y.push('foo');

console.log(y); // ['foo']

y.unshift("foo2");

console.log(y); // ['foo2', 'foo']

y.pop();

console.log(y); // ['foo2']

लेकिन इनमें से कुछ भी नहीं:

const x = {};
x = {foo: 'bar'}; // error - re-assigning

const y = ['foo'];
const y = ['bar']; // error - re-declaring

const foo = 'bar'; 
foo = 'bar2';       // error - can not re-assign
var foo = 'bar3';   // error - already declared
function foo() {};  // error - already declared

4
तो आपका मतलब है कि यह बग नहीं है, लेकिन इसे इस तरह से काम करना चाहिए? क्योंकि मुझे लगा कि स्थिरांक का विचार यह है कि इसे बदला नहीं जा सकता। मूल रूप से एक प्रोग्रामर को भरोसा है कि चाहे कुछ भी हो, मेरे स्थिरांक के अंदर कुछ भी मूल्य नहीं बदल सकता है।
सल्वाडोर डाली

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

6
हां, यह इस तरह से काम करने वाला है, आप स्थिरांक को फिर से असाइन नहीं कर रहे हैं, यह अभी भी एक ही संदर्भ है, आप बस निरंतर संदर्भों को जोड़ रहे हैं, और सरणियाँ और ऑब्जेक्ट "सूचियों" की तरह हैं, उन्हें संशोधित करता है संदर्भ को न बदलें या स्थिर को फिर से घोषित करें।
एडीनो

26
@ साल्वाडोरदाली: निरंतर और केवल पढ़ने के लिए दो अलग चीजें हैं। आपका चर स्थिर है , लेकिन यह जिस सरणी को इंगित कर रहा है वह केवल पढ़ने के
मैट बरलैंड

43

ऐसा इसलिए होता है क्योंकि आपका स्थिरांक वास्तव में सरणी का संदर्भ संग्रहीत करता है । जब आप अपने सरणी में कुछ जोड़ते हैं तो आप अपने निरंतर मूल्य को संशोधित नहीं कर रहे हैं, लेकिन यह जिस सरणी को इंगित करता है। ऐसा ही होगा यदि आपने किसी स्थिरांक को कोई वस्तु सौंपी है और उसकी किसी भी संपत्ति को संशोधित करने का प्रयास किया है।

यदि आप किसी सरणी या ऑब्जेक्ट को फ्रीज करना चाहते हैं तो इसे संशोधित नहीं किया जा सकता है, तो आप उस Object.freezeविधि का उपयोग कर सकते हैं , जो पहले से ही ECMAScript 5 का हिस्सा है।

const x = Object.freeze(['a'])
x.push('b')
console.log(x) // ["a"]

1
उसी तर्क से, five5 पर एक स्थिर सेट वास्तव में 5 का मान नहीं है, यह केवल संख्या 5 का एक संदर्भ है। इसलिए यदि मैं करूं तो five++मैं निरंतर परिवर्तन नहीं कर रहा हूं, बस वह संख्या जो इसे इंगित करता है।
एंथनी

3
@ एंथनी संदर्भ केवल सरणियों और वस्तुओं के लिए काम करता है, न कि आदिम मूल्यों के लिए
गुइलहर्मे सेहान

1
@Anthony आपके उदाहरण में, आप उस संख्या को बदल रहे हैं जो चर fiveबिंदुओं (चर five5 नंबर के लिए एक लेबल हुआ करता था, अब यह एक अलग संख्या की ओर इशारा कर रहा है: 6)। प्रश्न (और इस उत्तर) में उदाहरण में, xहमेशा एक ही सूची को इंगित करता है; अगर xकांस्ट है तो आप इसे अलग सूची में नहीं ला सकते। एकमात्र अंतर यह है कि एक ही सूची विकसित या सिकुड़ सकती है; यह केवल सरणियों और वस्तुओं के लिए ही संभव है और आदिम के लिए नहीं।
श्रीवत्सआर

9

यह प्रत्येक प्रोग्रामिंग भाषा के साथ सुसंगत व्यवहार है जिसके बारे में मैं सोच सकता हूं।

सी पर विचार करें - सरणियाँ सिर्फ गौरवशाली संकेत हैं। एक निरंतर सरणी का अर्थ केवल यह है कि सूचक का मान नहीं बदलेगा - लेकिन वास्तव में उस पते पर मौजूद डेटा मुफ़्त है।

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

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


4

कॉन्स्ट डिक्लेरेशन एक वैल्यू का रीड-ओनली रेफरेंस बनाता है। इसका मतलब यह नहीं है कि यह जो मूल्य रखता है वह अपरिवर्तनीय है, बस यह कि चर पहचानकर्ता को आश्वस्त नहीं किया जा सकता है। उदाहरण के लिए, उस मामले में जहां सामग्री एक वस्तु है, इसका मतलब है कि वस्तु की सामग्री (जैसे, इसके पैरामीटर) को बदला जा सकता है।

इसके अलावा, एक महत्वपूर्ण नोट:

वैश्विक स्थिरांक खिड़की वस्तु के गुण नहीं बनते हैं ...

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const


3

मुझे लगता है कि यह आपको इस मुद्दे पर और अधिक स्पष्टता प्रदान करेगा: https://codeburst.io/explaining-value-vs-reference-in-javascript-647a975e12a0

मूल रूप से यह constहमेशा स्मृति में एक ही पते की ओर इशारा करता है। आप उस पते में संग्रहीत मान को बदल सकते हैं लेकिन वह पता नहीं बदल सकते constजो इंगित कर रहा है।

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

जहां जैसे कि constगैर-आदिम मूल्य की ओर इशारा किया जाता है, तो पते के मूल्य को संपादित करना संभव है।


1

इस लेख के माध्यम से आया कि क्यों मैं इसे परिभाषित करने के बाद भी एक वस्तु को अद्यतन करने में सक्षम था const । तो यहाँ मुद्दा यह है कि यह सीधे वस्तु नहीं है, लेकिन इसमें वे विशेषताएँ हैं जिन्हें अद्यतन किया जा सकता है।

उदाहरण के लिए, मेरी वस्तु दिखती है:

const number = {
    id:5,
    name:'Bob'
};

उपरोक्त उत्तरों ने सही ढंग से बताया कि यह ऑब्जेक्ट है जो कि कॉन्स्ट है और इसकी विशेषता नहीं है। इसलिए, मैं आईडी या नाम को अपडेट करने में सक्षम हो जाऊंगा:

number.name = 'John';

लेकिन, मैं ऑब्जेक्ट को स्वयं अपडेट नहीं कर पाऊंगा जैसे:

number = {
    id:5,
    name:'John'
  };

TypeError: Assignment to constant variable.

1
आपका उदाहरण एक व्यावहारिक और सही वर्णन है
इब्राहिम

0

क्योंकि कॉन्स्ट में आप किसी ऑब्जेक्ट के मान बदल सकते हैं, इसलिए ऑब्जेक्ट वास्तव में असाइनमेंट डेटा को स्टोर नहीं करता है, बल्कि इसके बजाय यह इंगित करता है। इसलिए जावास्क्रिप्ट में आदिम और वस्तुओं के बीच अंतर है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.