2012-06-01 11 views
25

कैसे स्थिरांक वस्तुओं के गुणों के रूप में सेट नहीं किया जा सकता है जो स्वयं चर हैं?कॉन्स्ट कीवर्ड का उपयोग कर ऑब्जेक्ट्स के गुणों के रूप में जावास्क्रिप्ट स्थिरांक कैसे बनाएं?

const a = 'constant' // all is well 
// set constant property of variable object 
const window.b = 'constant' // throws Exception 
// OR 
var App = {}; // want to be able to extend 
const App.goldenRatio= 1.6180339887 // throws Exception 

और संदर्भ द्वारा पारित स्थिरांक कैसे अचानक परिवर्तनीय हो जाते हैं? संपादित करें: मुझे पता है कि ऐप नहीं होगा (या बल्कि ... नहीं होना चाहिए) mutable हो; यह सिर्फ एक प्रेक्षण है ...

(function() { 
    const App; 
    // bunch of code 
    window.com_namespace = App; 
}()); 
window.com_namespace; // App 
window.com_namespace = 'something else'; 
window.com_namespace; // 'something else' 

कैसे एक अच्छी तरह से संगठित, एक्स्टेंसिबल, वस्तु उन्मुख, अकेले स्थिरांक युक्त पुस्तकालय namespaced कर सकते हैं इन सीमाओं के साथ किया जा सकता है?

संपादित करें: मैं zi42 विश्वास है, लेकिन मैं सिर्फ पूछने के लिए why

उत्तर

33

आप स्थिरांक के साथ ऐसा नहीं कर सकते हैं। कुछ बर्ताव करता है जैसे कि आप चाहते हैं करने के लिए ही संभव तरीका है, लेकिन स्थिरांक का उपयोग नहीं कर रहा है, एक गैर लिखने योग्य संपत्ति को परिभाषित करने के लिए है: क्यों एक const एक समारोह के लिए पारित चर हो जाता है के रूप में

var obj = {}; 
Object.defineProperty(obj, "MY_FAKE_CONSTANT", { 
    value: "MY_FAKE_CONSTANT_VALUE", 
    writable: false, 
    enumerable: true, 
    configurable: true 
}); 

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

संपादित:

हालांकि इस अवधि पायथन समुदाय में व्यापक उपयोग किया है, समान: कि ध्यान देने योग्य बात के लिए @pst करने के लिए धन्यवाद शाब्दिक जावास्क्रिप्ट में वास्तव में "संदर्भ द्वारा पारित" नहीं कर रहे हैं, लेकिन call-by-sharing का उपयोग कर वस्तुओं जावा और विजुअल बेसिक जैसी अन्य भाषाओं में अर्थशास्त्र को अक्सर कॉल-बाय-वैल्यू के रूप में वर्णित किया जाता है, जहां मान वस्तु के संदर्भ के रूप में इंगित किया जाता है।

+0

संदर्भ द्वारा पारित वस्तुओं नहीं हैं? – danronmoon

+0

हां, लेकिन 'const obj = {}' थोड़े बेकार है क्योंकि संदर्भ स्थिर रहेगा, लेकिन आप अभी भी ऑब्जेक्ट को संशोधित कर सकते हैं। –

+4

नहीं ऑब्जेक्ट्स * नहीं * "संदर्भ द्वारा पारित" हैं (यह सबसे अच्छा एक अस्पष्ट वाक्यांश है)। एक कार्यान्वयन आम तौर पर "संदर्भ के * मूल्य * से गुजरता है" लेकिन जावास्क्रिप्ट में महत्वपूर्ण बात यह है कि [ऑब्जेक्ट शेयरिंग सेमेन्टिक्स द्वारा कॉल करें] (http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing)। मजेदार तथ्य: * ईसीएमएस्क्रिप्ट विनिर्देश शब्द "संदर्भ" * का उपयोग नहीं करता है। –

3
const person = { 
    name: "Nicholas" 
}; 

// works 
person.name = "Greg"; 



console.log(person) //Greg 

है यही कारण है कि Object.defineProperty का उपयोग

1

आप const declaration से भूल नहीं करना चाहिए "एक मूल्य के केवल पढ़ने के लिए संदर्भ बनाता है। यह मूल्य यह रखती है मतलब यह नहीं है अपरिवर्तनीय है, सिर्फ इतना है कि चर पहचानकर्ता पुन: असाइन नहीं किया जा सकता "

से तो आप एक अन्य ब्लॉक में यह redeclare कर सकते हैं 'चलो', एक समान तरीके से स्थिरांक कीवर्ड काम

const MyConst = 5; 
console.log('global MyConst =', MyConst); //global MyConst = 5 
if(true){ 
    const MyConst = 99 
    console.log('in if block, MyConst =', MyConst); //in if block, MyConst = 99 
} 
console.log('global MyConst still 5 ?', MyConst===5); //global MyConst still 5 ? true 

बस @ ज़ियाद-साब की तरह अगर आप किसी ऑब्जेक्ट प्रॉपर्टी को स्थिर की तरह कार्य करने की इच्छा रखते हैं, तो आपको इसे एक गैर-लेखन योग्य संपत्ति के रूप में परिभाषित करना होगा।

यदि आपका निरंतर वस्तु है और संपत्ति बदलना नहीं चाहिए, तो वस्तु को अपरिवर्तनीय बनाने के लिए Object.freeze() का उपयोग करें।

(function(){ 
    var App = { }; 
    // create a "constant" object property for App 
    Object.defineProperty(App , "fixedStuff", { 
    value: Object.freeze({ prop:6 }), 
    writable: false, 
    enumerable: true, 
    configurable: true 
    }); 

    Object.defineProperty(window, "com_namespace", { 
    value: App, 
    writable: false, 
    enumerable: true, 
    configurable: true 
    }); 
})() 

com_namespace.newStuff = 'An extension'; 
com_namespace.fixedStuff.prop = 'new value'; // do nothing! 
console.log(com_namespace.fixedStuff.prop); //6 
3

ऐसा करने का एक आसान तरीका है। मुझे यह पैटर्न पसंद है। सरल वस्तुओं।

window.Thingy = (function() { 

    const staticthing = "immutable"; 

    function Thingy() { 

     let privateStuff = "something"; 

     function get() { 
      return privateStuff; 
     } 

     function set(_) { 
      privateStuff = _; 
     } 
     return Object.freeze({ 
      get, 
      set, 
      staticthing 
     }); 
    } 

    Thingy.staticthing = staticthing; 
    return Object.freeze(Thingy); 
})(); 

let myThingy = new Thingy(); 

Thingy.staticthing = "fluid"; 

myThingy.staticthing = "fluid"; 

console.log(Thingy.staticthing); // "immutable" 
console.log(myThingy.staticthing); // "immutable" 

ऑब्जेक्ट।फ्रीज यहाँ

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze

काम कर रहा है अगर आप आप इसे निर्माता समारोह पर वस्तु शाब्दिक वापसी बंद को छोड़ कर उदाहरण बंद स्थिर संपत्ति छोड़ सकते हैं चाहता हूँ।

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