2012-05-04 17 views
17

कहें कि मैं इस जावास्क्रिप्ट स्निपेट को निष्पादित करने का प्रयास कर रहा हूं। मान लें कि अविकसित वर्रों और विधियों को कहीं और, घोषित किया गया है, और something और somethingElse बुलियन-सत्य का मूल्यांकन करते हैं।एक कोशिश ब्लॉक में जावास्क्रिप्ट स्कोप

try { 
    if(something) { 
     var magicVar = -1; 
    } 

    if(somethingElse) { 
     magicFunction(magicVar); 
    } 
} catch(e) { 
    doSomethingWithError(e); 
} 

मेरा प्रश्न है: magicVar के दायरे क्या है और यह यह magicFunction में पारित करने के लिए के रूप में मेरे द्वारा की गई ठीक है?

+1

मुझे ऐसा लगता है जैसे इस चर गुंजाइश के बारे में सिर्फ एक सवाल, एक कोशिश ब्लॉक के भीतर नहीं चर गुंजाइश है। –

उत्तर

17

जावास्क्रिप्ट समारोह गुंजाइश है।इसका मतलब है कि magicvar समारोह यह है कि समारोह के अंत करने के लिए सभी तरह से घोषित की गई की शुरुआत से उपलब्ध नहीं होगा, भले ही उस वक्तव्य कभी निष्पादित नहीं करता है। इसे परिवर्तनीय hoisting कहा जाता है। एक ही बात कार्यों घोषणाओं, जो बारी में समारोह उत्थापन कहा जाता है के साथ होता है।

यदि चर वैश्विक स्तर पर घोषित किया गया है, तो यह सब कुछ पर दिखाई देगा। यह जावास्क्रिप्ट में वैश्विक चर को बुरा मानने का कारण है।

आपका उदाहरण में magicFunction अगर something गलत है undefined पारित करेंगे, क्योंकि magicVar कुछ भी करने के लिए आवंटित नहीं किया गया है।

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

alert(a); //alerts "undefined" 
var a; 

पॉप प्रश्नोत्तरी: निम्नलिखित कोड क्या करता है?

(function() { 
    x = 2; 
    var x; 
    alert(x); 
})(); 
alert(x); 
+1

आपके द्वारा दिया गया उदाहरण काफी अच्छा नहीं है क्योंकि यह वैसे भी 'अपरिभाषित' था, क्योंकि 'window.a'' अपरिभाषित ' – gdoron

+0

@gdoron मुझे यकीन नहीं है कि मैं देख रहा हूं कि आप क्या प्राप्त कर रहे हैं। यदि आप केवल 'अलर्ट (ए)' को चलाने की कोशिश करते हैं, तो यह एक त्रुटि को 'ए है' अपरिभाषित '' फेंक देगा। –

+0

बात यह है कि 'a' _can_ को अपरिभाषित किया जाना चाहिए क्योंकि यह बहिर्वाह में अपरिभाषित है। आप 'वर x' आप अभी भी एक ही परिणाम प्राप्त निकालते हैं पर इस [डेमो] (http://jsfiddle.net/gdoron/H8c4n/3/) एक नजर डालें। – gdoron

1

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

अपने मामले में

तो, अगर something गलत है लेकिन somethingelse सच है, आप अपनी पहली तर्क किया जा रहा undefined साथ magicFunction कॉल करेंगे।

let कीवर्ड, जावास्क्रिप्ट 1.9 में बनाया है और उपलब्ध (आज के रूप में, 3 मई वां 2012, और जहाँ तक मुझे पता है) केवल फ़ायरफ़ॉक्स में, scoped अर्थ विज्ञान आप शायद करने के लिए इस्तेमाल कर रहे हैं के साथ चर की घोषणा की।

5
  • जावास्क्रिप्ट में केवल कार्यों के लिए एक नया संदर्भ -closure पैदा करते हैं।
  • एक चर का हर परिभाषा वास्तव में इसके दायरे के शीर्ष पर चर की घोषणा और जगह है जहाँ परिभाषा है पर एक काम है।

वर

  • समारोह-दायरे वाले अपने कार्य के शीर्ष करने के
  • उत्तोलक एक ही दायरे में एक ही नाम के
  • redeclarations कोई-ऑप्स हैं

आप

function bar() { 
    var x = "outer"; 

    function foo() { 
     alert(x); // {undefined} Doesn't refer to the outerscope x 
     // Due the the var hoising next:   
     x = 'inner'; 
     var x; 
     alert(x); // inner 

    } 
    foo(); 
} 

bar();​ 

bar();​ 

Demo

तो foo समारोह कुछ इस तरह बदल जाती है: MDN scope cheat sheet

कारण hoisting को आप इस तरह की बातें भी कर सकते हैं पढ़ सकते हैं

function foo() { 
    var x; 
    alert(x); // {undefined} Doesn't refer to the outerscope x 
    // Due the the var hoising next:   
    x = 'inner'; 
    alert(x); // inner 
}​ 

मेरा सवाल है: MagicVar का दायरा क्या है डी क्या यह जादू समारोह में पास करना ठीक है जैसा मैंने किया है?

परिभाषित ठीक ..., हाँ कोड मान्य है, लेकिन यह कम पठनीय फिर अगर चर घोषणाओं शीर्ष पर थे, बस इतना ही है।

+0

मैं फाड़ा हूँ! मैं तुम्हारा और पीटर ओल्सन दोनों से प्यार करता हूँ। एक अपवित्र है :) – user5243421

+0

@ डैरेनग्रीन। **:) ** बुरा मत मानो। आपको लगता है कि आपको लगता है कि सबसे अच्छा जवाब चुनें। (मैं Stackoverflow विचार है कि स्वीकार किए जाते हैं जवाब शीर्ष करने के लिए पॉप पसंद नहीं है {मैं _hoisting_ सुना है? :)}, यह भावना पुरुष जो शायद सवाल पर कम ज्ञान है तय करते हैं कि जो जवाब सबसे अच्छा है नहीं है ।) अगर यह पीटर का जवाब है तो मैं इसके साथ अच्छा हूं, मैं जवाबों से प्रतिस्पर्धा नहीं करता हूं। – gdoron

+0

आपकी धोखा शीट लिंक अप्रचलित सामग्री माना जाता है। उस पृष्ठ पर बड़ी चेतावनी सलाखों से प्यार करें - आप इसे याद नहीं करेंगे! हाहा – jcollum

3

जावास्क्रिप्ट के कारण "उत्थापन" (यह गूगल), अपने चर घोषणा कोड अनुवाद हो जाता है के रूप में:

function yourFunction() { 
    var magicVar; 
    try { 
     if(something) { 
      magicVar = -1; 
     } 

     if(somethingElse) { 
      magicFunction(magicVar); 
     } 
    } catch(e) { 
     doSomethingWithError(e); 
    } 

} //end of your function 

"उत्थापन" सभी चर घोषणाओं समारोह के शीर्ष पर ले जाता है। तो magicVar फ़ंक्शन में हर जगह उपलब्ध है, लेकिन यह तब तक अनिर्धारित है जब तक कि आप इसे कोई मान न दें।

आपका चर समारोह गुंजाइश है।

14

के बारे में कैसे जावास्क्रिप्ट var के साथ इस संभालती है, लेकिन मैंने सोचा कि मैं let स्थिति से निपटने, जिसे अन्य अच्छा जवाब में से बहुत सारे ...

एक चर try ब्लॉक के अंदर let साथ परिभाषित किया गया है, तो यह नहीं हो जाएगा catch (या finally) ब्लॉक (रों) अंदर दायरे में। इसे संलग्न ब्लॉक में परिभाषित करने की आवश्यकता होगी।

उदाहरण के लिए, निम्नलिखित कोड ब्लॉक में, सांत्वना उत्पादन "आउटसाइड" हो जाएगा:

let xyz = "Outside"; 

try { 
    let xyz = "Inside"; 

    throw new Error("Blah"); 
} catch (err) { 
    console.log(xyz); 
} 
संबंधित मुद्दे