यह सवाल अनुभवी डेवलपर्स को भी क्यों परेशान करता है?
\nयदि आपने कभी JavaScript में लिखा है, तो आपने निश्चित रूप से फंक्शन घोषित करने के इन दोनों तरीकों को देखा होगा। वे दिखने में समान लगते हैं, लेकिन पूरी तरह से अलग व्यवहार करते हैं। Stack Overflow पर इस प्रश्न ने हजारों व्यूज़ और दर्जनों पृष्ठों की चर्चा एकत्र की है। क्यों? क्योंकि var functionName = function() {} और function functionName() {} के बीच अंतर न समझने से ऐसी बग्स होती हैं जिन्हें पकड़ना मुश्किल होता है।
आज हम इस विषय को एक बार और हमेशा के लिए समझ लेंगे। आप जानेंगे कि function declaration और function expression क्या हैं, hoisting कैसे काम करता है, और कब किस विधि का उपयोग करना चाहिए। चलिए शुरू करते हैं!
\n\nसिंटैक्स के पीछे क्या छिपा है?
\nबुनियादी बातों से शुरू करते हैं। पहला विकल्प Function Declaration (फंक्शन घोषणा) है:
\nfunction greet() {\n console.log('नमस्ते!');\n}\nदूसरा Function Expression (फंक्शनल एक्सप्रेशन) है:
\nconst greet = function() {\n console.log('नमस्ते!');\n};\nध्यान दें: पहले मामले में, फंक्शन का एक नाम है और वह पंक्ति की शुरुआत में है। दूसरे में, हम एक अनाम फंक्शन को greet वेरिएबल में असाइन कर रहे हैं। लेकिन सबसे दिलचस्प बात तब शुरू होती है जब हम देखते हैं कि JavaScript इन घोषणाओं को कैसे प्रोसेस करता है।
मुख्य अंतर: Hoisting (होइस्टिंग)
\nHoisting JavaScript का एक तंत्र है जिसमें कोड निष्पादित होने से पहले वेरिएबल और फंक्शन की घोषणाओं को उनके स्कोप के शीर्ष पर ले जाया जाता है। लेकिन यह declaration और expression के लिए अलग-अलग काम करता है।
\n\nFunction Declaration पूरी तरह से ऊपर उठ जाता है
\nजब आप function functionName() {} का उपयोग करते हैं, तो JavaScript फंक्शन की पूरी घोषणा को ऊपर 'उठा' देता है। इसका मतलब है कि आप कोड में घोषित होने से पहले फंक्शन को कॉल कर सकते हैं:
sayHello(); // "नमस्ते!"\n\nfunction sayHello() {\n console.log('नमस्ते!');\n}\nकोड बिना किसी त्रुटि के निष्पादित होगा। यह सुविधाजनक है, लेकिन शुरुआती लोगों को भ्रमित कर सकता है।
\n\nFunction Expression ऊपर नहीं उठता
\nvar functionName = function() {} के साथ कहानी अलग है। केवल वेरिएबल की घोषणा ऊपर उठती है, लेकिन उसका मान नहीं। फंक्शन अपनी जगह पर रहता है:
sayHello(); // TypeError: sayHello is not a function\n\nvar sayHello = function() {\n console.log('नमस्ते!');\n};\nऐसा क्यों? क्योंकि var वेरिएबल sayHello की घोषणा को ऊपर उठाता है (मान undefined के साथ), और फंक्शन का असाइनमेंट केवल एक्सप्रेशन वाली पंक्ति पर होता है। इसलिए, इस पंक्ति से पहले sayHello का मान undefined है, और इसे फंक्शन के रूप में कॉल करने का प्रयास त्रुटि उत्पन्न करता है।
वैसे, यदि आप var को let या const से बदलते हैं, तो त्रुटि अलग होगी — ReferenceError: Cannot access 'sayHello' before initialization। यह इसलिए है क्योंकि let और const घोषणा के क्षण तक प्रारंभ नहीं होते (तथाकथित 'टेम्पोरल डेड ज़ोन')।
स्कोप: एक और अड़चन
\nfunction declaration और function expression दोनों स्कोप के नियमों का पालन करते हैं। लेकिन एक बारीकियाँ हैं।
\n\nFunction Declaration ब्लॉक के भीतर दिखाई देता है
\nहालाँकि function declaration ऊपर उठता है, इसका स्कोप ब्लॉक तक सीमित होता है (सख्त मोड में):
\n'use strict';\nif (true) {\n function greet() {\n console.log('ब्लॉक के अंदर');\n }\n greet(); // "ब्लॉक के अंदर"\n}\ngreet(); // ReferenceError: greet is not defined (सख्त मोड में)\nगैर-सख्त मोड में, ऐसी घोषणा बाहर 'रिस' जाएगी, लेकिन इस पर भरोसा नहीं करना चाहिए।
\n\nFunction Expression अपने वेरिएबल में रहता है
\nfunction expression के साथ सब कुछ अनुमानित है: फंक्शन केवल वहीं उपलब्ध है जहाँ वेरिएबल उपलब्ध है। यदि स्थानांतरित