क्या मुझे उस फ़ंक्शन के भीतर फ़ंक्शन का उपयोग करना चाहिए जो केवल एक अन्य फ़ंक्शन में उपयोग किए जाते हैं?


30

विशेष रूप से, मैं जावास्क्रिप्ट में लिख रहा हूँ।

मान लीजिए कि मेरा प्राथमिक कार्य फ़ंक्शन ए है। यदि फ़ंक्शन ए फ़ंक्शन बी को कई कॉल करता है, लेकिन फ़ंक्शन बी का उपयोग कहीं और नहीं किया जाता है, तो क्या मुझे फ़ंक्शन बी को फ़ंक्शन ए के भीतर रखना चाहिए?

क्या यह अच्छा अभ्यास है? या क्या मुझे अभी भी फंक्शन A के समान फंक्शन B को एक ही दायरे में रखना चाहिए?

जवाबों:


32

मैं आमतौर पर नेस्टेड कार्यों के पक्ष में हूं, विशेष रूप से जावास्क्रिप्ट में।

  • जावास्क्रिप्ट में, किसी फ़ंक्शन की दृश्यता को सीमित करने का एकमात्र तरीका इसे किसी अन्य फ़ंक्शन के अंदर नेस्ट करना है।
  • सहायक कार्य एक निजी कार्यान्वयन विवरण है। इसे एक ही दायरे में रखना एक वर्ग के निजी कार्यों को सार्वजनिक करने के समान है।
  • यदि यह अधिक सामान्य उपयोग के लिए निकला है, तो इसे स्थानांतरित करना आसान है, क्योंकि आप आश्वस्त हो सकते हैं कि सहायक वर्तमान में केवल एक फ़ंक्शन द्वारा उपयोग किया जाता है। दूसरे शब्दों में, यह आपके कोड को अधिक सामंजस्यपूर्ण बनाता है।
  • आप अक्सर मापदंडों को समाप्त कर सकते हैं, जो फ़ंक्शन हस्ताक्षर और कार्यान्वयन को कम क्रिया करता है। यह वैरिएबल को वैश्विक बनाने जैसी बात नहीं है। यह एक निजी विधि में एक वर्ग के सदस्य का उपयोग करने की तरह है।
  • आप संघर्षों के बारे में चिंता किए बिना सहायक कार्यों को बेहतर, सरल नाम दे सकते हैं।
  • सहायक फ़ंक्शन खोजने में आसान है। हां, ऐसे उपकरण हैं जो आपकी मदद कर सकते हैं। यह अभी भी आसान है कि स्क्रीन को थोड़ा ऊपर उठाएं।
  • कोड स्वाभाविक रूप से अमूर्तता के पेड़ का एक प्रकार बनाता है: जड़ में कुछ सामान्य कार्य, कई कार्यान्वयन विवरणों में शाखा। यदि आप फ़ंक्शन तह / टकराने के साथ एक संपादक का उपयोग करते हैं, तो घोंसला बनाना अमूर्त के समान स्तर पर बारीकी से संबंधित कार्यों का एक पदानुक्रम बनाता है। यह आपके लिए आवश्यक स्तर पर कोड का अध्ययन करने और विवरणों को छिपाने के लिए बहुत आसान बनाता है।

मुझे लगता है कि इस तथ्य का बहुत विरोध होता है कि ज्यादातर प्रोग्रामर या तो सी / सी ++ / जावा परंपरा में लाए गए थे, या किसी और द्वारा पढ़ाए गए थे। जब हम कार्यक्रम सीख रहे थे, तब नेस्टेड फ़ंक्शंस स्वाभाविक नहीं लगते क्योंकि हम उनके संपर्क में नहीं आते। इसका मतलब यह नहीं है कि वे उपयोगी नहीं हैं।


14

आपको इसे कई कारणों से वैश्विक दायरे में रखना चाहिए।

  • कॉलर में एक सहायक कार्य करने से कॉलर की लंबाई बढ़ जाती है। फ़ंक्शन की लंबाई लगभग हमेशा एक नकारात्मक संकेतक है; छोटे कार्यों को समझना, याद रखना, डिबग करना और बनाए रखना आसान होता है।

  • यदि सहायक फ़ंक्शन का एक समझदार नाम है, तो उस नाम को पढ़ना पास की परिभाषा को देखने की आवश्यकता के बिना पर्याप्त है। यदि आप ऐसा करने के लिए, फोन करने वाले समारोह को समझने के लिए तो यह है कि फोन करने वाले बहुत ज्यादा कर रहा है, या एक साथ अमूर्त की भी कई स्तरों पर काम कर रहा है में सहायक परिभाषा को देखने के लिए की जरूरत है।

  • विश्व स्तर पर उपलब्ध सहायक होने के कारण अन्य कार्यों को इसे कॉल करने की अनुमति देता है यदि यह आम तौर पर सभी के बाद उपयोगी हो जाता है। यदि सहायक उपलब्ध नहीं है, तो आपको इसे काटने और पेस्ट करने, या इसे भूल जाने और इसे फिर से लागू करने, खराब करने, या किसी अन्य फ़ंक्शन को लंबे समय तक बनाए रखने के लिए लुभाया जाता है।

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

संपादित करें

जितना मैंने सोचा था उससे अधिक विवादास्पद प्रश्न निकला। स्पष्टीकरण देना:

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

और आसान पुन: उपयोग धारणाओं कि अगर एक सबरूटीन के बारे में बात करता हो जाते हैं और अधिक व्यापक रूप से इस्तेमाल, आप पूरी तरह से जगह की इसे बाहर ले जाने और उपयुक्त जगह है, जैसे एक स्ट्रिंग उपयोगिता पुस्तकालय में या अपने वैश्विक विन्यास रजिस्ट्री में यह डाल करने के लिए तैयार हैं। यदि आप अपने कोड को उस तरह से ऑर्डर नहीं करना चाहते हैं, तो आप सबरूटीन को घोंसले में डाल सकते हैं, ठीक उसी तरह जैसे आप एक सामान्य विधि ऑब्जेक्ट के साथ एक अधिक "ब्लॉकी" भाषा में करेंगे।


धन्यवाद, सभी बहुत अच्छे अंक। एक साइड नोट पर, मुझे आम तौर पर अपने कार्यों का आदेश कैसे देना चाहिए? उदाहरण के लिए, इस समय, छोटे कार्यक्रमों के साथ मैं उन्हें केवल वर्णानुक्रम में क्रमबद्ध करता हूं। लेकिन क्या मुझे सहायक और कॉलर कार्यों को एक साथ समूहित करना चाहिए? मुझे लगता है कि मुझे कम से कम अपने कार्यों को तोड़ना चाहिए, उदाहरण के लिए, आवेदन के किन हिस्सों पर वे लागू होते हैं?
गैरी

मैं एक लंबे समय में विधि परिभाषाओं को परेशान नहीं किया है। यदि आप किसी भी व्यावसायिकता की डिग्री के साथ कार्यक्रम करते हैं, तो आपके पास एक ऐसा वातावरण होना चाहिए जो आपको किसी भी तरह केस्ट्रोक्स के साथ किसी भी परिभाषा में कूदने की अनुमति दे। इसलिए लघु विधियाँ उपयोगी हैं, लेकिन छोटी या अच्छी तरह से क्रमबद्ध श्रेणी की फाइलें बहुत कम मान देती हैं। (बेशक, जावास्क्रिप्ट का उपयोग सभी परिभाषाओं को उनके उपयोग से ऊपर रखने की आवश्यकता होती है या परिणाम तकनीकी रूप से अपरिभाषित व्यवहार होगा - यह याद नहीं कर सकते कि क्या अभी भी ऐसा है या नहीं।)
किलन फ़ॉथ

2
यह एक बेहतरीन जवाब है। टूटे हुए इनकैप्सुलेशन की समस्या कुछ ऐसी है जो आंतरिक कार्यों का उपयोग करते समय विचार नहीं करती है।
sbichenko

2
ग्लोबल्स एक कोड गंध है। वे अनावश्यक युग्मन का कारण बनते हैं जो रिफ्लेक्टिंग को रोकता है, वे नाम संघर्ष का कारण बनते हैं, वे कार्यान्वयन विवरणों को उजागर करते हैं, आदि यह जावास्क्रिप्ट में विशेष रूप से खराब है, क्योंकि सभी चर परस्पर भिन्न होते हैं, कोड आमतौर पर सीधे तृतीय-पक्ष से लोड होता है, वहाँ (अभी तक) नहीं है एक व्यापक रूप से उपलब्ध मॉड्यूल सिस्टम, या "लेट" का व्यापक रूप से उपलब्ध कार्यान्वयन। इस तरह के शत्रुतापूर्ण वातावरण में, हमारे पास एकमात्र रक्षात्मक रणनीति एक-शॉट कार्यों के अंदर इनकैप्सुलेशन है।
वारबो

1
"कक्षाओं की भूमिका को पूरा करना" जेएस को लिखने की कोशिश कर रहा है जैसे कि यह कुछ और था। "वर्गों की भूमिका" क्या है? टाइप की जाँच? प्रतिरूपकता? संकलन का मंचन किया? विरासत? प्रश्न में स्कूपिंग शामिल है, इसलिए मेरा मानना ​​है कि आप वर्गों के क्रूड स्कैपिंग नियमों का मतलब है। यह सिर्फ हिरन गुजर रहा है: वर्गों को कैसे अलग किया जाना चाहिए ? PHP उन्हें वैश्विक बनाता है, जो बिना किसी अतिक्रमण के प्रदान करता है। पायथन स्कोप कक्षाएं लेक्सिकली होती हैं, लेकिन अगर आप लेक्सिकली स्कॉप्ड ब्लॉक में हैं, तो दूसरे, क्लास-स्कॉप्ड ब्लॉक में सब कुछ क्यों लपेटें? जेएस के पास ऐसी अतिरेक नहीं है: बस उतना ही स्कोपिकल स्कोप का उपयोग करें जितना आपको चाहिए।
वारबो

8

मैं एक बंद के भीतर दोनों कार्यों को जगह देने के लिए, एक तीसरे रास्ते का प्रस्ताव करने जा रहा हूं। ऐसा लगेगा:

var functionA = (function(){
    function functionB() {
        // do stuff...
    }

    function functionA() {
        // do stuff...
        functionB();
        // do stuff...
    }

    return functionA;
})();

हम एक IIFE में दोनों कार्यों की घोषणा को लपेटकर बंद का निर्माण करते हैं । IIFE का रिटर्न मान सार्वजनिक फ़ंक्शन है, जो फ़ंक्शन के लिए नाम के एक चर में संग्रहीत है। सार्वजनिक समारोह को ठीक उसी तरह से लागू किया जा सकता है जैसे कि इसे एक वैश्विक कार्य के रूप में घोषित किया गया था functionA()। ध्यान दें कि रिटर्न वैल्यू फ़ंक्शन है , फ़ंक्शन के लिए कॉल नहीं है, इस प्रकार अंत में कोई भी पैरेंस नहीं है।

दो कार्यों को इस तरह लपेटकर, functionB अब पूरी तरह से निजी है, और इसे बंद होने से बाहर नहीं पहुँचा जा सकता है, लेकिन केवल दिखाई देता है functionA। यह वैश्विक नाम स्थान को अव्यवस्थित नहीं कर रहा है , और परिभाषा की अव्यवस्था नहीं कर रहा है functionA


0

फ़ंक्शन ए के भीतर फ़ंक्शन बी को परिभाषित करना ए के आंतरिक चर को फ़ंक्शन बी एक्सेस देता है।

तो, एक फ़ंक्शन A के भीतर परिभाषित एक फ़ंक्शन B यह आभास देता है (या कम से कम व्यवसायिकता) कि B A के स्थानीय चर का उपयोग या परिवर्तन कर रहा है। A के बाहर B को परिभाषित करते समय यह स्पष्ट करता है कि B नहीं करता है।

इसलिए, कोड की स्पष्टता के लिए, मैं A के भीतर B को केवल तभी परिभाषित करूंगा जब B को A के स्थानीय चर का उपयोग करने की आवश्यकता हो, यदि B का एक स्पष्ट उद्देश्य है जो A से स्वतंत्र है, तो मैं निश्चित रूप से A के बाहर इसे परिभाषित करूंगा।


-1

आपको इसे घोंसला नहीं बनाना चाहिए, क्योंकि अन्यथा बाहरी फ़ंक्शन को कॉल करने पर हर बार नेस्टेड फ़ंक्शन को फिर से बनाया जाएगा।


-3

चूंकि फ़ंक्शन बी का उपयोग कहीं और नहीं किया गया है, इसलिए आप इसे फ़ंक्शन ए के भीतर एक मज़ाक बना सकते हैं क्योंकि यह एकमात्र कारण है जो मौजूद है।


1
इस के लिए कुछ भी कर दिया अंक पर पर्याप्त जोड़ने के लिए प्रतीत नहीं होता है और पहले 3 जवाब में बताया गया है
कुटकी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.