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


21

एक ट्यूटोरियल (जावास्क्रिप्ट के लिए) जो मैं कर रहा हूं वह बताता है कि हम इस तरह से एक फ़ंक्शन लिखते हैं:

function sayHello() {
   //Some comments explaining the next line
   window.alert("Hello");
}

वास्तविक जीवन में इस तरह के कुछ लिखने से क्या लाभ हैं? यदि हां, तो क्या लाभ हैं?


14
यह शायद आपको यह दिखाने की कोशिश कर रहा है कि अपने कार्यों को कैसे परिभाषित किया जाए।
डोभाल

4
मैं कोड को कभी भी इस तरह से नहीं लिखूंगा, इसे मानने के लिए - कोड प्रोग्रामर को आसानी से पढ़ने के लिए है, न कि दूसरे तरीके से। मोटापे के लिए एक ओफ्यूसकैटर का उपयोग करें।
रघ्घस

32
लाभ यह है कि यह एक फ़ंक्शन को मापदंडों के साथ लपेटता है । इस तरह यदि आप बाद में अपना ऐप स्पेनिश बनाना चाहते हैं, तो आपको केवल "हैलो" को एक स्थान पर "ओला" में बदलना होगा।
B पर Pieter B

9
@ पीटर वास्तव में, "होला"
संशोधित करते हैं

29
@PieterB - और अगर आपको "होला" की याद आती है, तो आपको इसे केवल एक जगह पर ठीक करना होगा।
डैनियल आर हिक्स

जवाबों:


60

कृपया मेरी स्मृति को क्षमा करें यदि मेरे पास यह गलत है ... जावास्क्रिप्ट मेरी पसंदीदा कार्यान्वयन भाषा नहीं है।

कई कारण हैं कि कोई क्यों नहीं चाहता है कि कोई अरग फंक्शन रैप एक और फंक्शन कॉल हो। जबकि साधारण कॉल window.alert("Hello");कुछ ऐसा है जिसकी आप कल्पना कर सकते हैं बजाय सीधे कॉल करने के sayHello()

लेकिन क्या हो अगर इसमें कुछ और हो? आपको एक दर्जन स्थान मिले हैं जहां आप कॉल करना चाहते हैं sayHello()और window.alert("Hello");इसके बजाय लिखा है । अब आप चाहते हैं कि यह ए window.alert("Hello, it is now " + new Date())। यदि आप उन सभी कॉल को लपेटते हैं जैसे sayHello()आप इसे एक जगह बदलते हैं। यदि आपने नहीं किया, तो आप इसे एक दर्जन स्थानों पर बदल देते हैं। यह अपने आप को दोहराता नहीं है । आप इसे करते हैं क्योंकि आप इसे भविष्य में एक दर्जन बार नहीं करना चाहते हैं।

मैंने अतीत में एक i18n / l10n लाइब्रेरी के साथ काम किया था जो पाठ के क्लाइंट साइड स्थानीयकरण करने के लिए फ़ंक्शंस का उपयोग करती थी। sayHello()फ़ंक्शन पर विचार करें । holaजब उपयोगकर्ता किसी स्पेनिश भाषा में स्थानीयकृत होता है तो आप इसका प्रिंट आउट ले सकते थे। यह कुछ इस तरह दिख सकता है:

function sayHello() {
  var language = window.navigator.userLanguage || window.navigator.language;
  if(language === 'es') { window.alert('Hola'); }
   else { window.alert("Hello"); }
}

हालाँकि, यह नहीं है कि पुस्तकालय कैसे काम करता है। इसके बजाय, इसमें फ़ाइलों का एक सेट था जो देखने में ऐसा था:

# English file
greeting = hello
# Spanish file
greeting = hola

और फिर पुस्तकालय ब्राउज़र भाषा सेटिंग का पता लगाएगा और फिर उपयुक्त स्थानीयकरण के साथ गतिशील फ़ंक्शन तैयार करेगा क्योंकि उचित स्थानीयकरण फ़ाइल के आधार पर एक नो-डिग्मेंट फ़ंक्शन कॉल के लिए वापसी मूल्य।

मैं यह कहने के लिए एक जावास्क्रिप्ट कोडर के लिए पर्याप्त नहीं हूं कि क्या यह अच्छा है या बुरा है ... बस यह है कि यह संभव दृष्टिकोण के रूप में देखा जा सकता है।

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

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


3
window.alertयह भी अक्सर विकास के दौरान एक प्लेसहोल्डर के रूप में उपयोग किया जाता है जब तक कि एक अच्छा मोडल / पॉपअप डिजाइन / कार्यान्वित नहीं किया जा सकता है, इसलिए, भाषा के मुद्दे के समान, इसे बहुत आसानी से स्विच किया जा सकता है। या यदि आपके पास पहले से ही एक है, तो लाइन के नीचे कुछ वर्षों में एक डिज़ाइन अपडेट के लिए समान परिवर्तनों की आवश्यकता हो सकती है।
इज़काता

34

मुझे लगता है कि कार्यान्वयन को छिपाने के लिए कभी-कभी यह उपयोगी है।

 function sayHello() {
  window.alert("Hello");
 }

और यह आपको बाद में इसे बदलने की सुविधा देता है

 function sayHello() {
  console.log("Hello");
 }

19

वास्तविक जीवन में इस तरह के कुछ लिखने से क्या लाभ हैं? यदि हां, तो क्या लाभ हैं?

  • केंद्रीकरण: हालांकि कार्यान्वयन एक एकल पंक्ति लंबी है, अगर यह एक ऐसी रेखा है जो अक्सर बदलती रहती है, तो आप शायद इसे एक ही स्थान पर बदलना पसंद करते हैं, जहाँ भी कहेंगेहेलो कहा जाता है।

  • निर्भरता को कम करना / छिपाना: आपके ग्राहक कोड को अब यह जानने की जरूरत नहीं है कि एक विंडो ऑब्जेक्ट है, और आप क्लाइंट कोड को प्रभावित किए बिना पूरे कार्यान्वयन को बदल भी सकते हैं।

  • अनुबंध की पूर्ति: क्लाइंट कोड एक मॉड्यूल की उम्मीद कर सकता है जिसमें एक SayHello फ़ंक्शन है। इस मामले में, भले ही तुच्छ हो, तो फ़ंक्शन होना चाहिए।

  • अमूर्त स्तरों की समाहितता: यदि क्लाइंट कोड उच्च स्तर के संचालन का उपयोग करता है, तो विंडो ऑब्जेक्ट्स के बजाय 'SayHello, sayBye' और कुछ अन्य 'sayXXX' फ़ंक्शन (s) के संदर्भ में क्लाइंट कोड लिखना आपके हित में है। वास्तव में, क्लाइंट कोड में आप जानना भी नहीं चाहेंगे कि 'विंडो' ऑब्जेक्ट जैसी कोई चीज है।


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

3
अन्य कारण अच्छे हैं लेकिन अमूर्त स्तरों का उल्लेख करने के लिए +1 है। स्पष्ट सार और अच्छे फ़ंक्शन नामों का उपयोग करने से पुराने कोड को पढ़ना और बनाए रखना बहुत आसान हो सकता है। उस बिंदु पर जहां sayHello () कहा जाता है, आप जरूरी नहीं कि इसे कैसे लागू किया जाता है, से संबंधित हैं, आप बस यह समझना चाहते हैं कि कोड की इस पंक्ति का इरादा क्या है। और sayHello () जैसा एक फ़ंक्शन नाम स्पष्ट करता है।
13

अमूर्त स्तरों का उल्लेख करने के लिए भी +1: ऐसा हो सकता है कि एक अमूर्त स्तर पर एक फ़ंक्शन के कार्यान्वयन में एक कम अमूर्त स्तर के दूसरे फ़ंक्शन के लिए एक कॉल शामिल हो। तो क्या?
जियोर्जियो

7

कमाल है कि एक भी व्यक्ति ने परीक्षण का उल्लेख नहीं किया है।

आपके द्वारा चुनी गई विशेष "लिपटी" रेखा window.alert('hello')वास्तव में इसका एक आदर्श उदाहरण है। windowवस्तु को शामिल करने वाली कोई भी चीज वास्तव में, परीक्षण करने के लिए वास्तव में दर्दनाक है। गुणा करें कि आपके आवेदन में 1000 गुना और मैं गारंटी देता हूं कि डेवलपर्स अंततः परीक्षण पर छोड़ देंगे। दूसरी ओर, यह सिर्फ sayHelloएक जासूस और परीक्षण है कि यह कहा जाता है के साथ समारोह clobber करने के लिए बहुत आसान है ।

एक अधिक व्यावहारिक उदाहरण - क्योंकि वास्तव में, जो वास्तव window.alert(...)में उत्पादन कोड में उपयोग करता है? - सिस्टम क्लॉक की जांच कर रहा है। उदाहरण के लिए, यह DateTime.Now.NET time(...)में C / C ++ या System.currentTimeMillis()जावा में रैपिंग होगा । आप वास्तव में उन पर निर्भरता में लपेटना चाहते हैं जिन्हें आप इंजेक्ट कर सकते हैं, क्योंकि वे न केवल (लगभग) असंभव हैं नकली / नकली, वे केवल-पढ़ने और गैर-नियतात्मक हैं । किसी फ़ंक्शन या पद्धति को कवर करने वाला कोई भी परीक्षण जो सिस्टम क्लॉक फ़ंक्शन का प्रत्यक्ष उपयोग करता है, आंतरायिक और / या यादृच्छिक विफलताओं से पीड़ित होने की अत्यधिक संभावना है।

वास्तविक आवरण एक 1-पंक्ति फ़ंक्शन है - return DateTime.Now- लेकिन यह आपको खराब-डिज़ाइन किए गए, गैर-परीक्षण योग्य ऑब्जेक्ट को लेने और इसे एक साफ और परीक्षण योग्य बनाने के लिए आवश्यक है। आप रैपर के लिए एक नकली घड़ी स्थानापन्न कर सकते हैं, और अपना समय जो चाहें सेट कर सकते हैं। समस्या सुलझ गयी।


2

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


2

आपके प्रश्न के पीछे की सोच यह प्रतीत होती है: "सिर्फ alert("Hello");सीधे ही क्यों नहीं लिखा ? यह बहुत आसान है।"

जवाब है, भाग में, क्योंकि आप वास्तव में कॉल नहीं करना चाहते हैं alert("Hello")- आप बस नमस्ते कहना चाहते हैं।

या: अपने फोन पर संपर्क क्यों स्टोर करें, जब आप सिर्फ फोन नंबर डायल कर सकते हैं? क्योंकि आप उन सभी नंबरों को याद नहीं करना चाहते हैं; क्योंकि नंबर डायल करना थकाऊ और त्रुटि-प्रवण है; क्योंकि संख्या बदल सकती है, लेकिन यह अभी भी दूसरे छोर पर एक ही व्यक्ति है। क्योंकि आप लोगों को कॉल करना चाहते हैं , न कि नंबरों को।

इसे अमूर्त, अप्रत्यक्ष, "छिपाने के कार्यान्वयन के विवरण" और यहां तक ​​कि "अभिव्यंजक कोड" जैसे शब्दों से भी समझा जाता है।

हर जगह कच्चे मूल्यों को लिखने के बजाय स्थिरांक का उपयोग करने के लिए एक ही तर्क लागू होता है। आप बस हर बार आपको π की जरूरत है, लेकिन धन्यवाद लिख सकते हैं3.141592...Math.PI

हम alert()खुद भी देख सकते हैं । कौन परवाह करता है कि यह कैसे निर्माण करता है और उस सतर्क संवाद को प्रदर्शित करता है? आप केवल उपयोगकर्ता को सचेत करना चाहते हैं। लिखने alert("Hello")और आपकी स्क्रीन पर पिक्सेल बदलने के बीच, कोड और हार्डवेयर का एक गहरा, गहरा स्टैक होता है, जिसमें प्रत्येक परत यह बताती है कि वह क्या चाहता है, और यह कि अगली परत विवरण का ध्यान रखती है जब तक कि गहरी संभव परत परत में कुछ बिट्स को नहीं हटा देती है वीडियो स्मृति।

आप वास्तव में वह सब नहीं करना चाहते हैं जो अपने आप को सिर्फ नमस्ते कहना है।

प्रोग्रामिंग - ठीक है, किसी भी कार्य, वास्तव में - प्रबंधनीय विखंडू में जटिल समस्याओं को तोड़ने के बारे में है। प्रत्येक चंक को हल करने से आपको एक बिल्डिंग ब्लॉक मिलता है, और पर्याप्त सरल बिल्डिंग ब्लॉक के साथ, आप बड़ी चीजों का निर्माण कर सकते हैं।

यह बीजगणित है।


-1

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

एक फ़ंक्शन जो केवल रिटर्न मान की गणना करता है, केवल उसके द्वारा दिए गए तर्कों का उपयोग करके, शुद्ध कहा जाता है ।

एक "फ़ंक्शन" जो एक क्रिया करता है वास्तव में एक प्रक्रिया है , जिसका प्रभाव होता है

किसी मूल्य की गणना के दौरान होने वाले किसी भी प्रभाव को साइड-इफेक्ट कहा जाता है , और जहां संभव हो उनसे बचना बेहतर होता है ("मुझे बस उस स्ट्रिंग की आवश्यकता थी, मुझे नहीं पता था कि यह डेटाबेस को हथौड़ा देगा!")।

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

उसी कारण से, हमें एक प्रक्रिया के अंदर प्रसंस्करण परिणामों से बचना चाहिए। परिणाम (यदि कोई है) हमारी कार्रवाई को वापस करना बेहतर है, और शुद्ध कार्यों के साथ किसी भी बाद के प्रसंस्करण को करना बेहतर है।

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

गणना के दौरान प्रभावों की आवश्यकता को कम करने के लिए, हमारे पास गणना हो सकती है जो प्रक्रियाओं को वापस करती है ; जैसे। अगर हमें कार्रवाई करने के बारे में निर्णय लेने की आवश्यकता है, तो हमारे पास एक शुद्ध कार्य हो सकता है जो एक प्रक्रिया चुन सकता है और इसे वापस कर सकता है, बजाय इसे सीधे निष्पादित करने के।

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


आप यहाँ OOP के खिलाफ पैरवी कर रहे हैं, जहाँ मूल सिद्धांत "बताओ, मत पूछो" है। इस सलाह के बाद कि बेकार "getFoo", "setFoo" और "एक्जीक्यूट" कॉल के साथ कोड को क्या होता है। OOP डेटा और व्यवहार के संयोजन के बारे में है, न कि उन्हें अलग करने के लिए।
हारून

@Aaronaught यह सच है कि मैं OOP के खिलाफ हूं, लेकिन मैं निश्चित रूप setFooसे कॉल की सिफारिश नहीं करूंगा , क्योंकि यह परस्पर डेटा को दर्शाता है। चर / गुणों की सामग्री को बदलना एक प्रभाव है, जो उस डेटा का उपयोग करके सभी गणनाओं को अशुद्ध हो जाता है। मैं executeप्रति se कॉल की सिफारिश नहीं करूंगा , लेकिन मैं उनके तर्कों के आधार पर कार्रवाई को निष्पादित करने के लिए प्रक्रियाओं की सिफारिश करूंगाrunFoo
वारबो

-2

मैं कहूंगा कि यह @MichaelT और @Sleiman Jneidi द्वारा दिए गए उत्तरों का एक संयोजन है।

शायद कोड में कई जगह हैं जहां आप उपयोगकर्ता को एक हैलो संदेश के साथ बधाई देना चाहते हैं ताकि आप उस विचार को एक विधि में पैक कर सकें। विधि में आप इसका अनुवाद कर सकते हैं या एक लंबे पाठ को प्रदर्शित करके एक सरल 'हैलो' पर विस्तार कर सकते हैं। इसके अलावा, आप अलर्ट के स्थान पर एक अच्छा JQuery संवाद का उपयोग करना चाह सकते हैं।

मुद्दा यह है कि कार्यान्वयन एक ही स्थान पर है। आपको बस एक जगह कोड बदलना होगा। (SayHello () शायद एक बहुत सरल उदाहरण है)


@downvoter (s) - अपने ज्ञान को हममें से बाकी लोगों के साथ साझा करने की देखभाल करें। क्या मेरी पोस्ट बस गलत है, बुरी तरह से लिखी गई है या क्या है?
पाओल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.