2010-12-10 12 views
13

जब हम बंद होने के अंदर एक विधि बना रहे हैं तो यह बंद होने के लिए निजी हो जाता है और जब तक हम इसे किसी भी तरीके से बेनकाब नहीं करते हैं तब तक इसका उपयोग नहीं किया जा सकता है।एक बंद करने के अंदर एक विधि का खुलासा

इसका खुलासा कैसे किया जा सकता है?

उत्तर

15

आप

var a = function() { 

    var b = function() { 
     // I'm private! 
     alert('go away!'); 
    }; 

    return { 
     b: b // Not anymore! 
    }; 

}; 

See it on jsFiddle इसे करने के लिए एक संदर्भ लौट सकते हैं ...।

आप bind it to the window object भी कर सकते हैं। लेकिन मैं ऊपर की विधि पसंद करता हूं, अन्यथा आप इसे वैश्विक चर के माध्यम से उजागर कर रहे हैं (window ऑब्जेक्ट की संपत्ति होने के नाते)।

+0

+1। ओपी, आपको यह ईबुक देखना चाहिए: http://addyosmani.com/blog/essentialjsdesignpatterns/। इसे "मॉड्यूल का खुलासा" पैटर्न के रूप में जाना जाता है। – simshaun

+0

धन्यवाद! क्या हम इसे एक तरह से बेनकाब कर सकते हैं यदि यह एक अनाम कार्य है? – paul

+0

@ पाउल हां, 'वापसी कार्य() {} '। – alex

7

आपको इसे किसी भी तरह से बाहर करने की आवश्यकता है।

उदाहरण:http://jsfiddle.net/patrick_dw/T9vnn/1/

function someFunc() { 

    var privateFunc = function() { 
     alert('expose me!'); 
    } 

    // Method 1: Directly assign it to an outer scope 
    window.exposed = privateFunc; 

    // Method 2: pass it out as a function argument 
    someOuterFunction(privateFunc); 

    // Method 3: return it 
    return privateFunc; 
} 

someFunc()(); // alerts "expose me!" 

function someOuterFunction(fn) { 
    fn(); // alerts "expose me!" 
} 

window.exposed(); // alerts "expose me!" 
+0

+1 के साथ मुझे लगता है कि यह एक योग्य है :) – alex

+0

विंडो एक वैश्विक वस्तु है। क्या यह एक विधि का पर्दाफाश करने के लिए वैश्विक वस्तु का उपयोग करने का एक अच्छा तरीका है? – paul

+0

@paul - मैं @alex से सहमत हूं और नहीं कहूंगा। मैंने इसे एक सामान्य उदाहरण के रूप में इस्तेमाल किया। आप इसे किसी भी दायरे में असाइन कर सकते हैं जिस पर आपके पास पहुंच है। – user113716

3

आप अलग उन में घोषित इस गुंजाइश (जो मंगलाचरण के आधार पर बदल सकते हैं) द्वारा कार्य या बंद करने के गुणों का पर्दाफाश।

function example(val) { 

    var value = val; 

    this.getVal = function() { 
     return value; 
    } 

    this.setVal = function(v) { 
     value = v; 
    } 
} 

var ex = new example(2); 
ex.getVal(); // == 2 
ex.setVal(4); // == null 
ex.getVal(); // == 4 

तरीके इस में घोषित चर वर का उपयोग कर घोषित उपयोग कर सकते हैं, लेकिन नहीं अन्य तरीके से 'दौर।

function example(val) { 

    var value = val; 

    var double = function(v) { 
     return 2 * v; 
    } 

    this.getDouble = function() { 
     return double(value); 
    } 
} 


var ex = new example(2); 
ex.getDouble(); // == 4 

समारोह गुंजाइश पर बंद। आप जो करना चाहते हैं वह उस फ़ंक्शन के संदर्भ को वापस करना है जिसके पास आपको आवश्यक दायरे तक पहुंच है ताकि आप इसे बाद के बिंदु पर आ सकें।

आप एक समारोह है कि बाद में कुछ बिंदु पर एक विशिष्ट विधि कॉल बनाने के लिए की जरूरत है,

var ex = new example(2); 
var delayed_call = function() { 
    return(ex.getDouble()); // == 4, when called 
} 
setTimeout(delayed_call, 1000); 

तो scoping एक मुद्दा है,

var ex = new example(2); 
var delayed_call = (function(ex_ref) { 
    return function() { 
     return(ex_ref.getDouble()); // == 4, when called 
    } 
})(ex); // create a new scope and capture a reference to ex as ex_ref 
setTimeout(delayed_call, 1000); 

आपको कम के साथ इस का सबसे इनलाइन कर सकते हैं की पठनीय उदाहरण,

setTimeout((function(ex_ref) { 
    return function() { 
     return(ex_ref.getDouble()); // == 4, when called 
    })(new example(2))) 
    , 1000 
); 

setTimeout नए दायरे में निष्पादन का प्रदर्शन करने का एक सुविधाजनक तरीका है।

var ex = new example(2); 
var delayed_call = function() { 
    return(ex.getDouble()); 
} 
delayed_call(); // == 4 
+0

धन्यवाद! ... स्पष्टीकरण के लिए ... – paul

0

प्रदर्शन प्रयोजनों के लिए आप इसे इस तरह से आह्वान कर सकते हैं:

var a = (function(){ 
    function _a(){} 
    _a.prototype = (function(){ 
    var _test = function(){ console.log("test"); }; 
    return { 
     test: _test 
    } 
    }()); 

    return new _a(); 
}()); 

// usage 
var x = a; 
x.test(); // "test" 
संबंधित मुद्दे