2014-12-20 6 views
8

में एक निजी फ़ंक्शन के भीतर से मैं सार्वजनिक फ़ंक्शन को कैसे कॉल करूं? जावास्क्रिप्ट मॉड्यूल पैटर्न में एक निजी फ़ंक्शन के भीतर से मैं सार्वजनिक फ़ंक्शन कैसे कॉल करूं?जावास्क्रिप्ट मॉड्यूल पैटर्न

उदाहरण के लिए

, निम्नलिखित कोड में,

var myModule = (function() { 
    var private1 = function(){ 
     // How to call public1() here? 
     // this.public1() won't work 
    } 

    return { 
     public1: function(){ /* do something */} 
    } 
})(); 

यह सवाल twicebefore कहा गया है, प्रत्येक के लिए किसी दूसरी स्वीकृत जवाब के साथ।

  1. इसे वापस करने से पहले रिटर्न ऑब्जेक्ट का संदर्भ सहेजें, और उसके बाद सार्वजनिक विधि तक पहुंचने के लिए उस संदर्भ का उपयोग करें। answer देखें।
  2. बंद करने में सार्वजनिक विधि का संदर्भ सहेजें, और सार्वजनिक विधि तक पहुंचने के लिए इसका उपयोग करें। answer देखें।

हालांकि ये समाधान काम करते हैं, वे ओओपी बिंदु से असंतोषजनक हैं। मेरा मतलब यह समझाने के लिए, चलो इन समाधानों में से प्रत्येक के साथ एक स्नोमैन का ठोस कार्यान्वयन करें और उन्हें सरल वस्तु के साथ तुलनात्मक रूप से तुलना करें।

स्नोमैन 1: संदर्भ सहेजें वापस जाने के लिए वस्तु

var snowman1 = (function(){ 
    var _sayHello = function(){ 
    console.log("Hello, my name is " + public.name()); 
    }; 

    var public = { 
    name: function(){ return "Olaf"}, 
    greet: function(){ 
     _sayHello(); 
    } 
    }; 
    return public; 
})() 

स्नोमैन 2: सार्वजनिक समारोह के संदर्भ में सहेजें

var snowman2 = (function(){ 
    var _sayHello = function(){ 
    console.log("Hello, my name is " + name()); 
    }; 
    var name = function(){ return "Olaf"}; 

    var public = { 
    name: name, 
    greet: function(){ 
     _sayHello(); 
    } 
    }; 
    return public; 
})() 

स्नोमैन 3: वस्तु शाब्दिक

var snowman3 = { 
    name: function(){ return "Olaf"}, 
    greet: function(){ 
     console.log("Hello, my name is " + this.name()); 
    } 
} 

हम देख सकते हैं कि तीन कार्यक्षमता में समान हैं और सटीक समान विधियां हैं।

हम सरल अधिभावी का एक परीक्षण चलाते हैं, लेकिन

var snowman = // snowman1, snowman2, or snowman3 
snowman.name = function(){ return "Frosty";} 
snowman.greet(); // Expecting "Hello, my name is Frosty" 
       // but snowman2 says "Hello, my name is Olaf" 

हम चाहते हैं कि # 2 विफल रहता है देखते हैं।

हम प्रोटोटाइप अधिभावी का एक परीक्षण चलाते हैं,

var snowman = {}; 
snowman.__proto__ = // snowman1, snowman2, or snowman3 
snowman.name = function(){ return "Frosty";} 
snowman.greet(); // Expecting "Hello, my name is Frosty" 
       // but #1 and #2 both reply "Hello, my name is Olaf" 

हम चाहते हैं कि दोनों # 1 और # 2 असफल देखते हैं।

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

है वहाँ एक रास्ता एक निजी एक से एक सार्वजनिक विधि कॉल करने के लिए इतना है कि सम्मान के साथ शाब्दिक एक वस्तु की तरह है, जिसके परिणामस्वरूप वस्तु कृत्यों व्यवहार को ओवरराइड करने के लिए:

तो, यह असली सवाल है?

+2

आपके द्वारा चर्चा की जाने वाली समस्याओं में एक महत्वपूर्ण नोट: मॉड्यूल पैटर्न की मेरी समझ यह है कि यह वास्तव में जेएस के प्रोटोटाइप/ओओपी पोलिमोफिज्म दृष्टिकोण का विकल्प है। इस प्रकार, मुझे लगता है कि यह आपके लिए दोनों का उपयोग करने से बचने के लिए समझ में आता है - मुझे यह नहीं लगता कि यह एक गड़बड़ी * प्रति * के रूप में नहीं है। – EyasSH

+0

@ आईएएसएसएच- इसका उपयोग इस तरह से किया जा सकता है, हालांकि मुझे लगता है कि यह एक आर्टेफैक्ट है जिसका उपयोग जानबूझकर सुविधा के बजाय किसी प्रकार की विरासत के लिए किया जा सकता है। ऐसा लगता है कि मुख्य रूप से निजी सदस्यों को अनुकरण करने के लिए उपयोग किया जाता है (या उन चीजों को उजागर नहीं करना जिन्हें दूसरों के साथ नहीं खेलना चाहिए) और प्रदर्शन में सुधार करने के लिए भी। – RobG

+1

@RobG, ठीक है, लेकिन प्रोटोटाइप पैटर्न के साथ चिपके रहते हुए आप बंद होने में निजी कार्यों को घोषित कर सकते हैं। उस स्थिति में, '' '''' का उपयोग करना ठीक है। मेरा मुद्दा यह है कि, यदि आप मॉड्यूल पैटर्न का उपयोग कर रहे हैं, तो मुझे लगता है कि मॉड्यूल <-> प्रोटोटाइप इंटरैक्शन अजीबता एक दृष्टिकोण का उपयोग न करने का वास्तविक कारण नहीं है। यदि आप सोचते हैं कि जो भी आपका कोड उपयोग कर रहा है, वह प्रोटोटाइप को पूरी तरह से चिपकने का एक कारण हो सकता है .. – EyasSH

उत्तर

2

ऑब्जेक्ट प्राप्त करने के लिए आप this का उपयोग कर सकते हैं ताकि आपकी विशेषाधिकार प्राप्त विधि greet पर कॉल किया जा सके।

फिर, आप उस मूल्य को अपनी निजी विधि _sayHello पर भेज सकते हैं, उदा। callapply का उपयोग कर, या एक तर्क के रूप:

var snowman4 = (function() { 
    var _sayHello = function() { 
     console.log("Hello, my name is " + this.name); 
    }; 
    return { 
     name: "Olaf", 
     greet: function() { 
      _sayHello.call(this); 
     } 
    }; 
})(); 

अब आप

var snowman = Object.create(snowman4); 
snowman.greet(); // "Hello, my name is Olaf" 
snowman.name = "Frosty"; 
snowman.greet(); // "Hello, my name is Frosty" 

और यह भी

snowman4.greet(); // "Hello, my name is Olaf" 
snowman4.name = "Frosty"; 
snowman4.greet(); // "Hello, my name is Frosty" 
+0

यह उत्तर मॉड्यूल पैटर्न में निजी कार्यों के भीतर से सार्वजनिक कार्यों को कॉल करने के सवाल को संबोधित नहीं करता है - विशेष रूप से, _sayHello() कॉल नाम() को कैसे होना चाहिए। आईआईएफई में शाब्दिक वस्तु को लपेटने से नमस्कार() को विशेषाधिकार नहीं मिलता है। –

+0

@ I-LinKuo हां, यह विशेषाधिकार प्राप्त है। यह स्वयं निष्पादन समारोह के अंदर घोषित निजी डेटा तक पहुंच सकता है। – Oriol

+0

हां, विशेषाधिकार प्राप्त था: यह स्वयं निष्पादन समारोह के भीतर घोषित निजी डेटा तक पहुंच सकता है। मैंने निजीकरण के बजाय इसे एक विशेषाधिकार प्राप्त विधि के साथ किया, लेकिन यह सच है कि उसने सीधे सवाल का जवाब नहीं दिया, इसलिए मैंने इसे ठीक किया। – Oriol

1

कर सकते हैं मॉड्यूल पैटर्न के साथ, आप में एक वस्तु के सभी innates छिपाने स्थानीय चर/फ़ंक्शन, और आमतौर पर आपके सार्वजनिक कार्यों में उन लोगों को नियोजित करते हैं। प्रत्येक बार एक मॉड्यूल पैटर्न के साथ एक नई वस्तु बनाई जाती है, उजागर कार्यों का एक नया सेट - अपने स्वयं के स्कोप्ड राज्य के साथ-साथ भी बनाया जाता है।

प्रोटोटाइप पैटर्न के साथ, आपके पास कुछ प्रकार की सभी वस्तुओं के लिए विधियों का एक ही सेट उपलब्ध है। इन विधियों के लिए क्या परिवर्तन this ऑब्जेक्ट है - दूसरे शब्दों में, यह उनका राज्य है। लेकिन this कभी छिपा हुआ नहीं है।

कहने की जरूरत नहीं है, उनको मिश्रण करना मुश्किल है। एक संभावित तरीका मॉड्यूल के परिणामी ऑब्जेक्ट के प्रोटोटाइप में Object.create के प्रोटोटाइप में उपयोग की जाने वाली विधियों को निकालने का तरीका है। उदाहरण के लिए:

var guardian = function() { 
    var proto = { 
     greet: function() { 
      console.log('I am ' + this.name()); 
     }, 
     name: function() { 
      return 'Groot'; 
     } 
    }; 
    var public = Object.create(proto); 
    public.argue = function() { 
     privateGreeting(); 
    }; 

    var privateGreeting = public.greet.bind(public); 
    return public; 
}; 

var guardian1 = guardian(); 
guardian1.argue(); // I am Groot 
var guardian2 = guardian(); 
guardian2.name = function() { 
    return 'Rocket'; 
}; 
guardian2.argue(); // I am Rocket 
var guardian3 = guardian(); 
guardian3.__proto__.name = function() { 
    return 'Star-Lord'; 
}; 
guardian3.argue(); // I am Star-Lord 
संबंधित मुद्दे