2015-07-10 6 views
5

मैं वास्तव में एक जावास्क्रिप्ट नोब नहीं हूं, हालांकि मेरे पूरे जीवन में मैं कभी इस पर नहीं आया हूं, लेकिन क्या मैं यह मानने में सही हूं कि जावास्क्रिप्ट को कुछ भी चलाने से पहले कार्यों को असाइन करना होगा?आदेश के बावजूद परिभाषित कार्य हैं?

मेरे सभी अनुभवों में, मुझे उम्मीद है कि यह 'अपरिभाषित' वापस लौटाएगा, लेकिन जाहिर है कि यह 'फ़ंक्शन' देता है।

function bar() { 
    return foo; 
    foo = 10; 
    function foo() {} 
    var foo = '11'; 
} 
alert(typeof bar()); 

क्या कोई मेरे लिए यह समझा सकता है?

+0

[जावास्क्रिप्ट फ़ंक्शन स्कोपिंग और होस्टिंग] के संभावित डुप्लिकेट (http://stackoverflow.com/questions/7506844/javascript-function-scoping-and-hoisting) – DTing

+0

हां। एक [* निष्पादन संदर्भ *] (http://ecma-international.org/ecma-262/6.0/index.html#sec-execution-contexts) दर्ज करने पर, किसी भी कोड को चलाने से पहले सभी फ़ंक्शन और परिवर्तनीय घोषणाएं संसाधित की जाती हैं। – RobG

उत्तर

7

जावास्क्रिप्ट के इस व्यवहार को hoisting कहा जाता है। एमडीएन (https://developer.mozilla.org/en-US/docs/Glossary/Hoisting) पर एक अच्छी व्याख्या है

जावास्क्रिप्ट में, फ़ंक्शंस और चर हो जाते हैं। होस्टिंग एक स्कोप (वैश्विक दायरा या वर्तमान फ़ंक्शन स्कोप) के शीर्ष पर घोषणाओं को स्थानांतरित करने का जावास्क्रिप्ट का व्यवहार है।

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

मूल रूप से, अगर आप इस तरह एक चर घोषित:

console.log(s);    // s === undefined 
var s = 'some string'; 

s घोषणा गुंजाइश की शुरुआत करने के लिए "फहराया" किया जाएगा (अर्थात वहाँ console.log के साथ लाइन पर कोई ReferenceError हो जाएगा)। वैरिएबल का मान उस पल में परिभाषित नहीं किया जाएगा हालांकि। एक चर को एक गुमनाम समारोह बताए साथ

ही जाता है, तो:

console.log(f);    // f === undefined 
f();      // TypeError: f is not a function 
var f = function() {};  // assigning an anonymous function as a value 
f();      // ok, now it is a function ;) 

चर फहराया जाएगा और इस प्रकार पूरे दायरे में दिखाई दे रहा, लेकिन यह मूल्य है, भले ही वह एक समारोह है, होगा अभी भी अपरिभाषित हो - इसलिए यदि आप इसे निष्पादित करने का प्रयास करते हैं तो त्रुटि। ताकि आप इसे भी गुंजाइश आप इसे घोषित किया है की पहली पंक्ति में चला सकते हैं

console.log(f);    // f === function f() 
f();      // we can already run it 
function f() {};   // named function declaration 

यह परिभाषा भी फहराया किया जाएगा:

दूसरी ओर यदि आप एक नामित समारोह घोषणा करते हैं।

+0

मैं वास्तव में "hoisting" शब्द को नापसंद करता हूं, यह एक गलत नाम है, और संदर्भित स्पष्टीकरण खराब है। यह अनुमान लगाता है कि कोड किसी भी तरह से स्थानांतरित हो गया है, यह नहीं है। असली जवाब यह है कि किसी कोड को निष्पादित करने से पहले फ़ंक्शन और परिवर्तनीय घोषणाएं * संसाधित * होती हैं। – RobG

+0

शानदार ढंग से समझाया गया, धन्यवाद, यह बहुत स्पष्ट है, मुझे यह भी पता नहीं था कि जावास्क्रिप्ट ने नेस्टेड फ़ंक्शंस के साथ ऐसा किया था, मैंने सोचा था कि यह केवल रूट स्कोप था .. मुझे बेवकूफ़ बनाओ –

+0

@RobG हाँ, उचित बिंदु। यह थोड़ी देर के लिए "स्वयं invoking कार्यों" के साथ हमारे जैसा ही था, है ना? मैं भी प्रशंसक नहीं हूं (आपको यह सुनना चाहिए कि इसका अनुवाद मेरी भाषा में कैसे किया जा रहा है, यह "ऊंचाई" जैसा है;)) अब यह काफी हद तक अपनाया गया शब्द है और मुझे लगता है कि अधिक जानकारी में नहीं जाने के दौरान यह समझा जाना आसान है (यहां तक ​​कि यदि सटीकता को थोड़ा सा बलिदान दिया जाता है) –

0

जावास्क्रिप्ट फ़ंक्शन में ठीक है ऑब्जेक्ट के अलावा कुछ भी नहीं है।

जब आप कहते हैं कि typeof बार(), बार समारोह में आप foo जो एक और function.You समारोह का सिर्फ लौटने नाम है लौट रहे हैं, इसलिए, यह foo के निर्माता वापसी फ़ंक्शन। इसलिए, आपके टाइपफ़foo constructor का मान प्राप्त करें जो फ़ंक्शन का प्रकार है। इसलिए, यह फ़ंक्शन को अलर्ट करता है।यह अभी भी foo उल्लेख क्योंकि closure

फिर बार defination में

की, आप foo लौटने, लेकिन इसकी परिभाषा अभी भी encountered.In जावास्क्रिप्ट नहीं जब अनुदेश, चर की घोषणा पार्स करते समय और है फ़ंक्शन वर्तमान फ़ंक्शन स्कोप में शीर्ष पर रखा गया है।

तो, अपने बयान

function bar() { 
    return foo; 
    foo = 10; 
    function foo() {} 
    var foo = '11'; 
} 

function bar() { 
    function foo() {} 
    return foo; 
    foo = 10; 

    var foo = '11'; 

यह जावा स्क्रिप्ट top hoist

} 
0

यह काफी आसानी से परीक्षण किया जाता है कहा जाता है जैसा होता है;

foo(1); 

function foo(i) { 
    if (bar()) { 
     alert("foo called, bar true, i = " + i); 
    }; 
} 

foo(2); 

function bar() { 
    return true; 
} 

foo(3); 

DEMO

यह दिखाता है कि जावास्क्रिप्ट भार कुछ भी निष्पादित करने से पहले सभी कार्य करता है। इससे कोई फ़र्क नहीं पड़ता कि ऑर्डर फ़ंक्शन परिभाषित किए गए हैं।

संबंधित मुद्दे