जावास्क्रिप्ट में परिभाषित होने से पहले मैं फ़ंक्शन का उपयोग क्यों कर सकता हूं?

यह कोड हमेशा विभिन्न ब्राउज़रों में भी काम करता है:

function fooCheck() {
  alert(internalFoo());//We are using internalFoo() here...

  return internalFoo();//And here, even though it has not been defined...

  function internalFoo() { return true; } //...until here!
}

fooCheck();

मुझे एक संदर्भ नहीं मिला कि यह क्यों काम करना चाहिए, हालांकि। मैंने पहली बार जॉन रेसिग के प्रस्तुति नोट में यह देखा, लेकिन इसका उल्लेख केवल किया गया था। उस मामले के लिए वहां या कहीं भी कोई स्पष्टीकरण नहीं है।

क्या कोई मुझे प्रबुद्ध कर सकता है?

0
फ़ायरफ़ॉक्स के नए संस्करणों में, यदि कोड एक कोशिश/पकड़ में है तो यह काम नहीं करता है। यह पहेली देखें: jsfiddle.net/qzzc1evt
जोड़ा लेखक Joshua Smith, स्रोत

7 उत्तर

फ़ंक्शन "आंतरिक फ़ू" के शरीर को पार्सिंग समय पर कहीं जाना पड़ता है, इसलिए जब जेएस दुभाषिया द्वारा कोड पढ़ा जाता है (a.k.a पार्सिंग), फ़ंक्शन के लिए डेटा संरचना बनाई जाती है और नाम असाइन किया जाता है।

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

0
जोड़ा

मैंने केवल जावास्क्रिप्ट का उपयोग किया है। मुझे यकीन नहीं है कि इससे मदद मिलेगी, लेकिन यह आपके जैसा बात कर रहा है उससे बहुत समान दिखता है और कुछ अंतर्दृष्टि दे सकता है:

http://www.dustindiaz.com/javascript-function-declaration-ambiguity/

0
जोड़ा
लिंक मर चुका है
जोड़ा लेखक Leonardo, स्रोत
लिंक मर चुका है।
जोड़ा लेखक Jerome Indefenzo, स्रोत
लिंक अब मर चुका नहीं है।
जोड़ा लेखक mwclarke, स्रोत

इसी कारण से निम्नलिखित वैश्विक नामस्थान में हमेशा foo डाल देंगे:

if (test condition) {
    var foo;
}
0
जोड़ा
असल में, यह बहुत अलग कारणों से है। if ब्लॉक कोई दायरा नहीं बनाता है, जबकि function() ब्लॉक हमेशा एक बनाता है। वास्तविक कारण यह था कि वैश्विक जावास्क्रिप्ट नामों की परिभाषा संकलन चरण में होती है, ताकि यदि कोड नहीं चलता है, तो नाम परिभाषित किया गया है। (क्षमा करें, टिप्पणी करने में इतना समय लगा)
जोड़ा लेखक Edu Felipe, स्रोत

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

यह अन्य प्रोग्रामिंग संदर्भों से अलग है जो आपके सभी स्रोत कोड को संसाधित (संकलित) करते हैं, किसी भी पुस्तकालयों के साथ इसे एक साथ जोड़ते हैं, और निष्पादन योग्य मॉड्यूल का निर्माण करते हैं, जिस बिंदु पर निष्पादन शुरू होता है।

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

जैसे ही आप जावास्क्रिप्ट से परिचित हो जाते हैं, आप उचित अनुक्रम में चीजों को लिखने की आपकी आवश्यकता के बारे में जानबूझकर जागरूक हो जाएंगे।

संशोधन: स्वीकृत उत्तर (उपर्युक्त) की पुष्टि करने के लिए, वेब पेज के स्क्रिप्ट अनुभाग के बावजूद फ़ायरबग का उपयोग करें। आप इसे फ़ंक्शन से फ़ंक्शन पर छोड़ देंगे, केवल पहले पंक्ति पर जाकर, वास्तव में किसी भी कोड को निष्पादित करने से पहले।

0
जोड़ा
आपके उत्तर के अंत में संशोधन के लिए +1, जो आवश्यक हिस्सा है।
जोड़ा लेखक hippietrail, स्रोत

function घोषणा जादू है और इसके पहचानकर्ता को कोड-ब्लॉक * में निष्पादित होने से पहले बाध्य होने का कारण बनता है।

यह एक फ़ंक्शन अभिव्यक्ति के साथ असाइनमेंट से अलग है, जिसका सामान्य शीर्ष-डाउन ऑर्डर में मूल्यांकन किया जाता है।

यदि आपने यह कहने के लिए उदाहरण बदल दिया है:

var internalFoo = function() { return true; };

यह काम करना बंद कर देगा।

समारोह घोषणा समारोह अभिव्यक्ति से काफी अलग है, भले ही वे लगभग समान दिखते हैं और कुछ मामलों में संदिग्ध हो सकते हैं।

यह ECMAScript मानक , अनुभाग 10.1 में प्रलेखित है .3 । दुर्भाग्यवश ईसीएमए -262 मानक मानकों द्वारा भी एक बहुत ही पठनीय दस्तावेज नहीं है!

*: युक्त फ़ंक्शन, ब्लॉक, मॉड्यूल या स्क्रिप्ट।

0
जोड़ा
मुझे लगता है कि यह वास्तव में पठनीय नहीं है। मैंने केवल उस अनुभाग को पढ़ा है जिस पर आपने 10.1.3 की ओर इशारा किया था और यह नहीं मिला कि इस व्यवहार के कारण प्रावधान क्यों होंगे। जानकारी के लिए धन्यवाद।
जोड़ा लेखक Edu Felipe, स्रोत
@ माथीस: सही।
जोड़ा लेखक bobince, स्रोत
इसे "hoisting" कहा जाता है, है ना?
जोड़ा लेखक Mathias Bynens, स्रोत
@ बॉबन्स ठीक है, मैंने खुद को संदेह करना शुरू कर दिया जब मुझे इस पृष्ठ पर "hoisting" शब्द का एक भी उल्लेख नहीं मिला। उम्मीद है कि इन टिप्पणियों में सही चीजों को सेट करने के लिए पर्याप्त Google रस है :)
जोड़ा लेखक Mathias Bynens, स्रोत
इस आलेख में कुछ उदाहरण हैं: जावास्क्रिप्ट-स्कोपिंग-एंड-होस्टिंग
जोड़ा लेखक Lombas, स्रोत

इसे HOISTING कहा जाता है - जहां इसे परिभाषित किया गया है, उससे पहले एक फ़ंक्शन को आमंत्रित करें (बुलाया जाता है)।

मैं दो अलग-अलग प्रकार के कार्यों के बारे में लिखना चाहता हूं:

Expression Functions & Deceleration Functions

  1. Expression Functions:

    A function expression can be stored in a variable so they do not need function names. They will also named as an anonymous function (a function without a name).

    To invoke (called) they are always need using a variable name. These kind of functions won't work if calls before where it has been defined which means Hoisting is not happening here. We always must define the expression function first and then invoke it.

    let lastName = function (family) {
     console.log("My last name is " + family);
    };
    let x = lastName("Lopez");
    

    This is how you can write in ECMAScript 6:

    lastName = (family) => console.log("My last name is " + family);
    
    x = lastName("Lopez");
    
  2. Deceleration Functions:

    Functions are declared with the following syntax are not executed immediately. They are "saved for later use" and will be executed later, when they are invoked (called upon). These type of functions work if you call them BEFORE or AFTER where they have been defined. If you call a deceleration function before where it has been defined - Hoisting - works properly.

    function Name(name) {
      console.log("My cat's name is " + name);
    }
    Name("Chloe");
    

    Hoisting example:

    Name("Chloe");
    function Name(name) {
       console.log("My cat's name is " + name);
    }
    
0
जोड़ा

कुछ भाषाओं में आवश्यकता होती है कि पहचानकर्ताओं को उपयोग से पहले परिभाषित किया जाना चाहिए। इसका एक कारण यह है कि संकलक स्रोत कोड पर एक ही पास का उपयोग करता है।

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

0
जोड़ा