2012-11-21 20 views
11

मैं जावास्क्रिप्ट में स्थिर गुणों का अनुकरण करने की कोशिश कर रहा हूं। कई स्थानों पर इसका उल्लेख किया गया है कि class.prototype.property कक्षा से विरासत में प्राप्त सभी वस्तुओं में स्थिर होगा। लेकिन मेरा पीओसी अन्यथा कहता है। कृपया एक बार देख ले:जावास्क्रिप्ट: class.property बनाम class.prototype.property स्थिर गुणों का अनुकरण करने के लिए

Class.prototype.property

//Employee class 
function Employee() { 
    this.getCount = function(){ 
     return this.count; 
    };  
    this.count += 1; 
} 
Employee.prototype.count = 3; 

var emp = [], i; 
for (i = 0; i < 3; i++) { 
    emp[i] = new Employee(); 
    console.log("employee count is "+ emp[i].getCount()); 
} 
/*Output is: 
employee count is 4 
employee count is 4 
employee count is 4*/ 

मेरे प्रश्न # 1 का उपयोग करना: इस स्थिर होने के लिए गए थे, तो नहीं गिनती का मूल्य 4.5 किया जाना चाहिए था , 6, आदि जैसे सभी ऑब्जेक्ट्स समान गणना चर साझा करते हैं?

तब मैंने कक्षा.प्रोटोटाइप के साथ एक और पीओसी किया और मुझे लगता है कि यह स्थिर है।

Class.property

//Employee class 
function Employee() { 
    this.getCount = function(){ 
     return Employee.count; 
    };  
    Employee.count++; 
} 
Employee.count = 3; 

var emp = [], i; 
for (i = 0; i < 3; i++) { 
    emp[i] = new Employee(); 
    console.log("employee count is "+ emp[i].getCount()); 
} 
/*Output is: 
employee count is 4 
employee count is 5 
employee count is 6*/ 

मेरे प्रश्न # 2 का उपयोग करना: कहीं मैंने देखा है class.property सीधे इस्तेमाल किया जा रहा है। मेरे उपरोक्त कोड को ध्यान में रखते हुए जावास्क्रिप्ट में स्थिर चर कैसे बने हैं?

या क्या मैंने यहां कुछ गलत कोड किया है? क्या यह सही धारणा नहीं है?

+2

मैं दूसरा रूप हर समय का उपयोग करें। – tjameson

+0

मुझे लगता है कि यह '** हमेशा एक ** इंस्टेंस ** बिंदु _determine-by-run-time ऑब्जेक्ट_ पर है, जबकि आपके कोड में कर्मचारी 'प्रोटोटाइप घोषणा" है। – Passerby

उत्तर

30

मेरा प्रश्न # 1: यदि यह स्थैतिक होना था, तो गिनती का मूल्य 4,5,6 आदि नहीं होना चाहिए क्योंकि सभी ऑब्जेक्ट्स समान गणना चर साझा करते हैं?

प्रोटोटाइप गुणों को उदाहरणों में साझा किया जाता है, लेकिन यदि किसी उदाहरण के पास संपत्ति की अपनी प्रति है, तो इसका उपयोग इसके बजाय होगा। उदाहरण पर संपत्ति को सौंपना इसे अपनी प्रतिलिपि देता है, और इसलिए यह प्रोटोटाइप का अब और उपयोग नहीं करता है।

+=, ++, और इसी तरह के ऑपरेटरों के परिणामस्वरूप असाइनमेंट होते हैं, और इसलिए वे इस व्यवहार को भी जन्म देते हैं।

पर विचार करें:

function Employee() { 
} 
Employee.prototype.count = 0; 

ऊपर कोड के रूप में, Employee.prototype के लिए स्मृति में एक वस्तु है। कुछ ASCII आर्ट:

+−−−−−−−−−−−−−−−−−−−−+ 
| Employee.prototype | 
+−−−−−−−−−−−−−−−−−−−−+ 
| count: 0   | 
+−−−−−−−−−−−−−−−−−−−−+

तो हम ऐसा करते हैं:

var e = new Employee(); 

अब जो एक संदर्भ वापस Employee.prototype गया है स्मृति में एक दूसरी वस्तु, है:

+−−−−−−−−−−−−−−−+ 
|  e   | 
+−−−−−−−−−−−−−−−+   +−−−−−−−−−−−−−−−−−−−−+ 
| [[Prototype]] |−−−−−−−−−>| Employee.prototype | 
+−−−−−−−−−−−−−−−+   +−−−−−−−−−−−−−−−−−−−−+ 
          | count: 0   | 
          +−−−−−−−−−−−−−−−−−−−−+

और अगर आप क्वेरी e.count:

console.log(e.count); 

... e के पास अपनी खुद की संपत्ति count नहीं है, इंजन e प्रोटोटाइप को ढूंढने, इसे ढूंढने और उस मान का उपयोग करने के लिए देखता है।

हालांकि, जब हम ऐसा करते हैं:

e.count += 1; // Or more idiomatically, `++e.count;` or `e.count++;` 

प्रदान करती है e उदाहरण पर count करने के लिए एक मूल्य है। यदि आप e.count क्वेरी

+−−−−−−−−−−−−−−−+ 
|  e   | 
+−−−−−−−−−−−−−−−+ 
| count: 1  |   +−−−−−−−−−−−−−−−−−−−−+ 
| [[Prototype]] |−−−−−−−−−>| Employee.prototype | 
+−−−−−−−−−−−−−−−+   +−−−−−−−−−−−−−−−−−−−−+ 
          | count: 0   | 
          +−−−−−−−−−−−−−−−−−−−−+

अब: e अब अपने खुदcount की प्रतिलिपि है

console.log(e.count); 

... इंजन e पर count पाता है, और पर गौर नहीं करता प्रोटोटाइप।

आप कोड में इस आशय देख सकते हैं:

function Employee() { 
 
} 
 
Employee.prototype.count = 0; 
 

 
var e = new Employee(); 
 
console.log(e.hasOwnProperty('count')); // false 
 
e.count += 1; 
 
console.log(e.hasOwnProperty('count')); // true 
 

 
console.log(e.count);     // 1 
 
console.log(Employee.prototype.count); // 0

यह भी मजेदार है:

var e = new Employee(); 
 

 
console.log(e.count);     // 0 
 
++Employee.prototype.count; 
 
console.log(e.count);     // 1

के बाद से(0) की अपनी प्रति count की प्रतिलिपि नहीं है, अगर हम वास्तव में Employee.prototype पर संपत्ति बढ़ाते हैं, तो हम अपडेट किए गए मान को देखते हैं कि हम इसे सीधे (Employee.prototype.count) या परोक्ष रूप से (e.count) पूछते हैं। इस पर

अंतिम नोट: e एक संपत्ति की अपनी एक प्रतिलिपि हो जाता है, तो आप इसे फिर से निकाल सकते हैं:

var e = new Employee(); 
 
console.log(e.count); // 0, because it's using `Employee.prototype.count` 
 
++e.count;    // Now `e` has its own `count` property 
 
console.log(e.count); // 1, `e`'s own `count` 
 
delete e.count;   // Now `e` doesn't have a `count` property anymore 
 
console.log(e.count); // 0, we're back to using `Employee.prototype.count`

delete अधिक ठीक remove ही कहा जाता है। यह वस्तुओं से गुण हटा देता है।

मेरा प्रश्न # 2: कहीं भी मैंने क्लास.प्रोपर्टी को सीधे इस्तेमाल नहीं किया है। मेरे उपरोक्त कोड को ध्यान में रखते हुए जावास्क्रिप्ट में स्थिर चर कैसे बने हैं?

दो तरीके:

  1. वास्तव में के रूप में आप यह किया है, Employee.sharedProperty

  2. एक समारोह के अंदर पूरे "वर्ग" को परिभाषित करने, और कहा कि समारोह के भीतर स्थानीय चर का उपयोग करके:

    var Employee = (function() { 
        var sharedVariable = 0; 
    
        function Employee() { 
         ++sharedVariable; 
         console.log("sharedVariable = " + sharedVariable); 
        } 
    
        return Employee; 
    })(); 
    

    सभी कार्यों कि बाहरी scoping समारोह में परिभाषित स्थानीय यह भीतर निर्धारित वेरिएबल के लिए उपयोग होगा। तो केवल एक चर है, एक बाहरी कॉल के लिए स्थानीय उस समारोह में Employee बनाता है।

    फिर, इस कोड:

    new Employee(); 
    new Employee(); 
    new Employee(); 
    new Employee(); 
    

    आउटपुट

    1 
    2 
    3 
    4
+0

इस सटीक स्पष्टीकरण के लिए धन्यवाद। जब मैंने देखा कि प्रोटोटाइप.प्रोपर्टीज के माध्यम से जावास्क्रिप्ट में स्थिर गुणों को बनाया जा सकता है और मेरे कोड ने अन्यथा किया तो मैं बहुत भ्रम में था। – riju

+0

इस सटीक स्पष्टीकरण के लिए धन्यवाद। तो, मूल रूप से Class.prototype.properties स्थिर है, केवल वस्तु .properties इस मामले में बदला जा रहा है। अगर मैंने इसके बजाय Employee.prototype.count + = 1 किया था, तो यह अपेक्षित के रूप में काम करता। तो एक निश्चित शॉट स्थैतिक संपत्ति कार्यान्वयन के लिए, आप सुझाव दे रहे हैं कि मैं अपने दूसरे कोड या आपके द्वारा उल्लिखित कार्यान्वयन के दूसरे तरीके के साथ जाता हूं। एक बार फिर धन्यवाद। – riju

+1

@riju: किसी भी तरह से, यह आप पर निर्भर है। यह इस बात पर निर्भर करता है कि आप कितनी सार्वजनिक जानकारी चाहते हैं। यदि आप 'कर्मचारी.count' का उपयोग करते हैं, और' कर्मचारी 'सार्वजनिक है, तो 'कर्मचारी.count' सार्वजनिक है - कहीं भी कोई भी कोड इसे अपडेट कर सकता है। जो उपयोगी हो सकता है। यदि आप मॉड्यूल पैटर्न (मेरा दूसरा उदाहरण) का उपयोग करते हैं, तो उस बाहरी स्कोपिंग फ़ंक्शन के भीतर केवल कोड को 'साझा किए गए' तक पहुंच है। असल में, यह 'कर्मचारी' कोड के लिए निजी है जिसे आप परिभाषित करते हैं। आप 'कर्मचारी.प्रोटोटाइप' में फ़ंक्शंस जोड़ सकते हैं, और जब तक आप स्कोपिंग फ़ंक्शन के भीतर ऐसा करते हैं, तो वे 'साझा किए गए' (लेकिन अन्य नहीं कर सकते हैं) का उपयोग कर सकते हैं। –

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

  • कोई संबंधित समस्या नहीं^_^