2009-09-17 13 views
28

संभव डुप्लिकेट:
Use of 'prototype' vs. 'this' in Javascript?जावास्क्रिप्ट उदाहरण कार्यों

जावास्क्रिप्ट कार्यों के विभिन्न प्रकार के मेरे समझ इस प्रकार हैं:

function MyObj() { 
    this.propOne = true; 
    this.publicInstanceFunc = function() { 
     if (propOne) 
      return 'public instance function'; 
    } 
    function privateFunc() { 
     return 'private function only visible inside this constructor'; 
    } 
} 

MyObj.prototype.protoFunc = function() { 
    if (this.propOne) 
     return 'prototype function shared amongst all instances of MyObj'; 
} 
  1. हैं ये सही है?
  2. किसी भी मामले में प्रोटोटाइप (उदा। protoFunc) बनाम कन्स्ट्रक्टर (उदाहरण के लिए publicInstanceFunc) पर किसी भी मामले में कार्य करना चाहिए?
  3. this का उपयोग प्रोटोटाइप कार्यों के भीतर संपत्तियों तक पहुंचने का सही तरीका है?

उत्तर

49

आप वास्तव में एक स्वयं को क्रियान्वित समारोह में पूरी बात लपेटकर के माध्यम से विशेषाधिकार का एक और स्तर जोड़ सकते हैं:

var MyObj = (function() { // scoping 
    var privateSharedVar = 'foo'; 

    function privateSharedFunction() { 
     // has access to privateSharedVar 
     // may also access publicSharedVar via explicit MyObj.prototype 
     // can't be called via this 
    } 

    function MyObj() { // constructor 
     var privateInstanceVar = 'bar'; 
     this.publicInstanceVar = 'baz'; 

     function privateInstanceFunction() { 
      // has access to all vars 
      // can't be called via this 
     }; 

     this.publicInstanceMethod = function() { 
      // has access to all vars 
      // also known as a privileged method 
     }; 
    } 

    MyObj.prototype.publicSharedVar = 'quux'; 

    MyObj.prototype.publicSharedMethod = function() { 
     // has access to shared and public vars 
     // canonical way for method creation: 
     // try to use this as much as possible 
    }; 

    return MyObj; 
})(); 

केवल 'सार्वजनिक' गुण this के माध्यम से बाहर से पहुँचा जा सकता है।

प्रदर्शन कारणों से, आपको 'इंस्टेंस' विधियों से बचना चाहिए: इनमें से प्रत्येक के लिए, प्रत्येक MyObject इंस्टेंस के लिए एक नई फ़ंक्शन ऑब्जेक्ट बनाई जानी चाहिए, जबकि प्रति 'साझा' विधि केवल एक ही फ़ंक्शन ऑब्जेक्ट है।

+0

धन्यवाद! अच्छा उत्तर! – mcjabberz

+0

इस प्रश्न/उत्तर को पुनर्जीवित करने के लिए खेद है, लेकिन क्या पैरों में बाहरी कार्य को लपेटना कुछ खास करता है? जैसे कैसे है (फ़ंक्शन() {})(); फ़ंक्शन से अलग() {}(); – Matt

+0

@ मैट: बाहरी माता-पिता फ़ंक्शन को शाब्दिक रूप से एक कथन के बजाय अभिव्यक्ति के रूप में व्याख्या करने के लिए मजबूर करते हैं; वे इस मामले में अनावश्यक हैं क्योंकि असाइनमेंट पहले से ही इस व्याख्या को मजबूर करता है, लेकिन इसके बिना, आपको एक वाक्यविन्यास त्रुटि मिलनी चाहिए यदि आप माता-पिता – Christoph

3

1) हाँ आपका कोड सही है।

2) मैं कन्स्ट्रक्टर फ़ंक्शन के भीतर परिभाषित कार्यों का उपयोग करता हूं, जब मैं कन्स्ट्रक्टर फ़ंक्शन के दायरे में निजी रूप से परिभाषित अन्य सदस्यों तक पहुंच बनाना चाहता हूं, उदाहरण के लिए, जब आप privileged methods बनाना चाहते हैं।

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

3) हाँ, अगर संपत्ति सार्वजनिक है आप एक प्रोटोटाइप बढ़ाया समारोह के अंदर this कीवर्ड का उपयोग करके इसे उपयोग करने में सक्षम नहीं हैं, के बाद से this अपने वस्तु का उदाहरण को दर्शाता है।

3

दूसरे बिंदु के बारे में, आप प्रोटोटाइप का विस्तार करते हैं ताकि सभी पहले से बनाई गई वस्तुओं को नई विधि मिल सके।

इसके अलावा, आप अंतर्निहित वस्तुओं (जैसे trim()string जोड़ने) के तरीकों को जोड़ने की अनुमति देता है।

4

क्या ये सही हैं?

एरर। अच्छा, यह निर्भर करता है कि आप क्या करना चाहते हैं। जावास्क्रिप्ट में क्लास/इंस्टेंस-स्टाइल विरासत को लागू करने के लिए कोई भी स्वीकार्य कैननिकल मॉडल नहीं है।

लेकिन इस:

if (propOne) 

शायद उस this.propOne में एक गलती है, मालिक वस्तु की संपत्ति है जबकि propOne अपने आप में एक चर है कि घोषित नहीं किया गया है (यह चूक है एक वैश्विक चर के लिए, लेकिन आमतौर पर एक गलतता है)।

किस मामले में किसी ने कन्स्ट्रक्टर (जैसे protInFunc) बनाम कन्स्ट्रक्टर (जैसे publicInstanceFunc) पर फ़ंक्शन डाले?

प्रोटोटाइप पर एक फ़ंक्शन सेट सभी ऑब्जेक्ट्स के बीच साझा किया गया एक ही फ़ंक्शन है। एकमात्र तरीका यह काम कर सकता है कि यह किस उदाहरण से संबंधित है, इसे 'इस' को पढ़कर पढ़ा जाता है।

कन्स्ट्रक्टर में 'इस' पर एक फ़ंक्शन सेट MyObj के प्रत्येक उदाहरण के लिए एक नया फ़ंक्शन है। आप संभवतः इसे 'इस' के बजाय बंद करने के आधार पर मालिक ऑब्जेक्ट से जुड़ने के वैकल्पिक तरीके के रूप में उपयोग कर सकते हैं, जो फ़ंक्शन-बाध्यकारी सामग्री को लिखने से बचा सकता है। यह ऑब्जेक्ट-ओरिएंटेशन की एक अलग शैली है जो आम तौर पर आप इस-आधारित शैली के साथ मिश्रण नहीं करेंगे।

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