2011-12-13 17 views
5

मैं इस कोड (JSFiddle)मैं इस "सार्वजनिक" विधि को सही ढंग से कैसे बढ़ा सकता हूं?

var OBJ = function(){ 
    var privateVar = 23; 
    var self = this; 

    return { 
     thePrivateVar : function() { 
      return privateVar; 
     }, 

     thePrivateVarTimeout : function() { 
      setTimeout(function() { alert(self.thePrivateVar()); } , 10); 
     } 
    } 

}(); 

alert(OBJ.thePrivateVar()); 

OBJ.thePrivateVarTimeout(); 

यह एक वास्तविक समस्या मैं आ रही है की एक अमूर्त है।

तो - मैं OBJ.thePrivateVarTimeout() पर 10 और फिर alert को 23 के साथ प्रतीक्षा करने की उम्मीद करता हूं (जिसे मैं इसे अन्य खुली विधि के माध्यम से एक्सेस करना चाहता हूं)।

हालांकि self सही ढंग से सेट नहीं लग रहा है। जब मैं self = this सेटिंग कर रहा हूं तो ऐसा लगता है कि this फ़ंक्शन का संदर्भ नहीं है बल्कि वैश्विक वस्तु का संदर्भ है। ऐसा क्यों है?

मैं सार्वजनिक विधि कैसे बना सकता हूं thePrivateVarTimeout अन्य सार्वजनिक विधि thePrivateVar पर कॉल करें?

+2

* ऐसा क्यों? * क्योंकि आप सामान्य रूप से कार्य बुला रहे हैं है ('समारोह()')। इस मामले में, यह 'हमेशा' वैश्विक वस्तु को संदर्भित करता है। यदि आप इसे किसी खाली ऑब्जेक्ट को संदर्भित करना चाहते हैं, तो इसे 'नया' के साथ कॉल करें या एक असाइन करें: 'var self = {}; '। –

+0

@ फ़ेलिक्सक्लिंग धन्यवाद यह 'स्वयं' सही ढंग से सेट करता है। हालांकि मैं अभी भी 'ThePrivateVar' को आमंत्रित करने के लिए इसका उपयोग नहीं कर सकता। मुझे लगता है कि रेनोस का जवाब यह है कि मुझे यह करना चाहिए। –

उत्तर

5
var OBJ = (function(){ 
    var privateVar = 23; 
    var self = { 
     thePrivateVar : function() { 
      return privateVar; 
     }, 

     thePrivateVarTimeout : function() { 
      setTimeout(function() { alert(self.thePrivateVar); } , 10); 
     } 
    }; 

    return self; 

}()); 

this === global || undefined एक बुलाए गए फ़ंक्शन के अंदर। ES5 में यह भी वैश्विक वातावरण है, ईएस 5 सख्त में यह अनिर्धारित है।

अधिक आम पैटर्न एक समारोह

var obj = (function() { 
    var obj = { 
    property: "foobar", 
    timeout: function _timeout() { 
     var that = this; 
     setTimeout(alertData, 10); 

     function alertData() { 
     alert(that.property); 
     } 
    } 
    } 

    return obj; 
}()); 

में एक स्थानीय मूल्य var that = this के रूप में उपयोग कर या एक .bindAll विधि का उपयोग शामिल होगा

var obj = (function() { 
    var obj = { 
    alertData: function _alertData() { 
     alert(this.property); 
    } 
    property: "foobar", 
    timeout: function _timeout() { 
     setTimeout(this.alertData, 10); 
    } 
    } 

    bindAll(obj) 

    return obj; 
}()); 


/* 
    bindAll binds all methods to have their context set to the object 

    @param Object obj - the object to bind methods on 
    @param Array methods - optional whitelist of methods to bind 

    @return Object - the bound object 
*/ 
function bindAll(obj, whitelist) { 
    var keys = Object.keys(obj).filter(stripNonMethods); 

    (whitelist || keys).forEach(bindMethod); 

    function stripNonMethods(name) { 
     return typeof obj[name] === "function"; 
    } 

    function bindMethod(name) { 
     obj[name] = obj[name].bind(obj); 
    } 

    return obj; 
} 
+0

धन्यवाद, मैंने पहला पैटर्न इस्तेमाल किया। मुझे वास्तव में 'ओबीजे' के संदर्भ में 'स्वयं' की आवश्यकता नहीं है - मुझे केवल एक दूसरे को कॉल करने में सक्षम होने के लिए सार्वजनिक तरीकों की आवश्यकता है। हालांकि फेलिक्स ने 'स्वयं' मुद्दे को भी संबोधित किया। –

+0

@ElRonnoco मैं व्यक्तिगत रूप से '.bindAll' पैटर्न पसंद करता हूं क्योंकि 'वह = यह' मेरी आंखों को खून बहता है। – Raynos

+1

@ रेनोस लाइन में 'pd.bindAll (obj) '' pd' क्या है या पीडी कहां से आता है? –

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