इम्यूटेबिलिटी कार्यात्मक प्रोग्रामिंग में एक मुख्य सिद्धांत है, और ऑब्जेक्ट-ओरिएंटेड प्रोग्राम्स को भी बहुत कुछ प्रदान करती है। एक म्यूटेबल ऑब्जेक्ट एक ऐसा ऑब्जेक्ट है जिसकी स्थिति को उसके बनाए जाने के बाद संशोधित किया जा सकता है। एक इम्यूटेबल ऑब्जेक्ट एक ऐसा ऑब्जेक्ट है जिसकी स्थिति को उसके बनाए जाने के बाद संशोधित नहीं किया जा सकता है।
जावास्क्रिप्ट में इम्यूटेबल ऑब्जेक्ट का उदाहरण क्या है?
जावास्क्रिप्ट में, कुछ बिल्ट-इन प्रकार (संख्याएं, स्ट्रिंग्स) इम्यूटेबल होते हैं, लेकिन कस्टम ऑब्जेक्ट्स आम तौर पर म्यूटेबल होते हैं।
कुछ बिल्ट-इन इम्यूटेबल जावास्क्रिप्ट ऑब्जेक्ट्स Math
, Date
हैं।
साधारण जावास्क्रिप्ट ऑब्जेक्ट्स पर इम्यूटेबिलिटी जोड़ने/अनुकरण करने के कुछ तरीके यहां दिए गए हैं।
ऑब्जेक्ट कॉन्स्टेंट प्रॉपर्टीज
writable: false
और configurable: false
को मिलाकर, आप अनिवार्य रूप से एक कॉन्स्टेंट (बदला नहीं जा सकता, फिर से परिभाषित या हटाया नहीं जा सकता) को एक ऑब्जेक्ट प्रॉपर्टी के रूप में बना सकते हैं, जैसे:
let myObject = {};
Object.defineProperty(myObject, 'number', {
value: 42,
writable: false,
configurable: false,
});
console.log(myObject.number); // 42
myObject.number = 43;
console.log(myObject.number); // 42
एक्सटेंशन को रोकें
यदि आप किसी ऑब्जेक्ट को नई प्रॉपर्टीज जोड़ने से रोकना चाहते हैं, लेकिन ऑब्जेक्ट की बाकी प्रॉपर्टीज को वैसे ही छोड़ना चाहते हैं, तो Object.preventExtensions(...)
को कॉल करें:
var myObject = {
a: 2,
};
Object.preventExtensions(myObject);
myObject.b = 3;
myObject.b; // undefined
नॉन-स्ट्रिक्ट मोड में, b
का निर्माण चुपचाप विफल हो जाता है। सख्त मोड में, यह एक TypeError
फेंकता है।
सील
Object.seal()
एक "सील्ड" ऑब्जेक्ट बनाता है, जिसका अर्थ है कि यह एक मौजूदा ऑब्जेक्ट लेता है और अनिवार्य रूप से उस पर Object.preventExtensions()
को कॉल करता है, लेकिन इसकी सभी मौजूदा प्रॉपर्टीज को configurable: false
के रूप में भी चिह्नित करता है।
तो, न केवल आप कोई और प्रॉपर्टी नहीं जोड़ सकते हैं, बल्कि आप किसी भी मौजूदा प्रॉपर्टी को फिर से कॉन्फ़िगर या हटा भी नहीं सकते हैं (हालांकि आप अभी भी उनके मानों को संशोधित कर सकते हैं)।
फ्रीज
Object.freeze()
एक फ़्रोजन ऑब्जेक्ट बनाता है, जिसका अर्थ है कि यह एक मौजूदा ऑब्जेक्ट लेता है और अनिवार्य रूप से उस पर Object.seal()
को कॉल करता है, लेकिन यह सभी "डेटा एक्सेसर्स" प्रॉपर्टीज को writable:false के रूप में भी चिह्नित करता है, ताकि उनके मानों को बदला न जा सके।
यह दृष्टिकोण उच्चतम स्तर की इम्यूटेबिलिटी है जिसे आप स्वयं ऑब्जेक्ट के लिए प्राप्त कर सकते हैं, क्योंकि यह ऑब्जेक्ट या उसकी किसी भी सीधी प्रॉपर्टी में किसी भी बदलाव को रोकता है (हालांकि, जैसा कि ऊपर उल्लेख किया गया है, किसी भी संदर्भित अन्य ऑब्जेक्ट की सामग्री अप्रभावित रहती है)।
var immutable = Object.freeze({});
किसी ऑब्जेक्ट को फ्रीज करने से ऑब्जेक्ट में नई प्रॉपर्टीज जोड़ने की अनुमति नहीं मिलती है और मौजूदा प्रॉपर्टीज को हटाने या बदलने से रोका जाता है। Object.freeze()
ऑब्जेक्ट की इन्यूमरेबिलिटी, कॉन्फ़िगरेबिलिटी, राइटेबिलिटी और प्रोटोटाइप को संरक्षित करता है। यह पास किए गए ऑब्जेक्ट को वापस करता है और एक फ़्रोजन कॉपी नहीं बनाता है।
इम्यूटेबिलिटी के क्या फायदे और नुकसान हैं?
फायदे
- आसान परिवर्तन पहचान - ऑब्जेक्ट समानता को संदर्भित समानता के माध्यम से एक प्रदर्शनकारी और आसान तरीके से निर्धारित किया जा सकता है। यह रिएक्ट और रेडक्स में ऑब्जेक्ट अंतरों की तुलना करने के लिए उपयोगी है।
- इम्यूटेबल ऑब्जेक्ट्स वाले प्रोग्राम्स के बारे में सोचना कम जटिल होता है, क्योंकि आपको इस बात की चिंता करने की आवश्यकता नहीं होती है कि कोई ऑब्जेक्ट समय के साथ कैसे विकसित हो सकता है।
- जब इम्यूटेबल ऑब्जेक्ट्स को फ़ंक्शन से वापस किया जाता है या पास किया जाता है, तो रक्षात्मक प्रतियों की अब आवश्यकता नहीं होती है, क्योंकि इम्यूटेबल ऑब्जेक्ट को इसके द्वारा संशोधित किए जाने की कोई संभावना नहीं होती है।
- संदर्भों के माध्यम से आसान साझाकरण - एक ऑब्जेक्ट की एक प्रति दूसरे के समान ही अच्छी होती है, इसलिए आप ऑब्जेक्ट्स को कैश कर सकते हैं या एक ही ऑब्जेक्ट को कई बार पुन: उपयोग कर सकते हैं।
- थ्रेड-सेफ - इम्यूटेबल ऑब्जेक्ट्स का उपयोग मल्टी-थ्रेडेड वातावरण में थ्रेड्स के बीच सुरक्षित रूप से किया जा सकता है क्योंकि उनके अन्य समवर्ती रूप से चलने वाले थ्रेड्स में संशोधित होने का कोई जोखिम नहीं होता है।
- ImmutableJS जैसी लाइब्रेरी का उपयोग करके, ऑब्जेक्ट्स को संरचनात्मक साझाकरण का उपयोग करके संशोधित किया जाता है और समान संरचनाओं वाले कई ऑब्जेक्ट्स के लिए कम मेमोरी की आवश्यकता होती है।
नुकसान
- इम्यूटेबल डेटा संरचनाओं और उसके संचालन के भोले-भाले कार्यान्वयन के परिणामस्वरूप बेहद खराब प्रदर्शन हो सकता है क्योंकि हर बार नए ऑब्जेक्ट बनाए जाते हैं। कुशल इम्यूटेबल डेटा संरचनाओं और संचालन के लिए लाइब्रेरी का उपयोग करने की सिफारिश की जाती है जो संरचनात्मक साझाकरण का लाभ उठाते हैं।
- मौजूदा ऑब्जेक्ट्स को संशोधित करने के बजाय कई छोटे ऑब्जेक्ट्स का आवंटन (और विलोपन) प्रदर्शन पर प्रभाव डाल सकता है। एलोकेटर या गार्बेज कलेक्टर की जटिलता आमतौर पर हीप पर ऑब्जेक्ट्स की संख्या पर निर्भर करती है।
- साइक्लिक डेटा संरचनाएं जैसे ग्राफ़ बनाना मुश्किल है। यदि आपके पास दो ऑब्जेक्ट हैं जिन्हें इनिशियलाइज़ेशन के बाद संशोधित नहीं किया जा सकता है, तो आप उन्हें एक-दूसरे को इंगित करने के लिए कैसे प्राप्त कर सकते हैं?
आप अपने स्वयं के कोड में इम्यूटेबिलिटी कैसे प्राप्त कर सकते हैं?
वैकल्पिक रूप से const
घोषणाओं का उपयोग करना है जो निर्माण के लिए ऊपर वर्णित तकनीकों के साथ संयुक्त हैं। ऑब्जेक्ट्स को "म्यूटेट" करने के लिए, स्प्रेड ऑपरेटर, Object.assign
, Array.concat()
आदि का उपयोग करें, ताकि मूल ऑब्जेक्ट को म्यूटेट करने के बजाय नए ऑब्जेक्ट बनाए जा सकें।
उदाहरण:
// एरे उदाहरण
const arr = [1, 2, 3];
const newArr = [...arr, 4]; // [1, 2, 3, 4]
// ऑब्जेक्ट उदाहरण
const human = Object.freeze({ race: 'human' });
const john = { ...human, name: 'John' }; // {race: "human", name: "John"}
const alienJohn = { ...john, race: 'alien' }; // {race: "alien", name: "John"}