सवाल जावास्क्रिप्ट में चर के दायरे क्या है?


जावास्क्रिप्ट में चर के दायरे क्या है? क्या उनके पास एक समारोह के बाहर के विपरीत एक ही गुंजाइश है? या इससे कोई फर्क पड़ता है? साथ ही, यदि चर वैश्विक रूप से परिभाषित किए गए चर संग्रहीत होते हैं?


1715
2018-02-01 08:27


मूल


यहाँ एक और अच्छा है संपर्क इस मुद्दे को ध्यान में रखने के लिए: "जावास्क्रिप्ट स्कोप और बंद करने की व्याख्या"। - Full-Stack Software Engineer
यहां एक लेख है जो इसे बहुत अच्छी तरह से समझाता है। जावास्क्रिप्ट चरणीय दायरे के बारे में आपको जो कुछ भी पता होना चाहिए - Saurab Parakh
पूर्व उल्लिखित काइल सिम्पसन की ई-बुक गीथूब पर पढ़ने के लिए उपलब्ध है, और यह आपको जावास्क्रिप्ट स्कॉप्स और क्लोजर के बारे में जानने की ज़रूरत है। आप इसे यहां देख सकते हैं: github.com/getify/You-Dont-Know-JS/blob/master/... यह का हिस्सा है "आप जेएस नहीं जानते" पुस्तक श्रृंखला, जो जावास्क्रिप्ट के बारे में अधिक जानना चाहते हैं, उनके लिए बहुत अच्छा है। - 3rik82


जवाब:


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

  1. एक वैश्विक स्तर पर स्कॉप्ड चर

    // global scope
    var a = 1;
    
    function one() {
      alert(a); // alerts '1'
    }
    
  2. स्थानीय दायरा

    // global scope
    var a = 1;
    
    function two(a) {
      // local scope
      alert(a); // alerts the given argument, not the global value of '1'
    }
    
    // local scope again
    function three() {
      var a = 3;
      alert(a); // alerts '3'
    }
    
  3. मध्यम: जावास्क्रिप्ट में ब्लॉक स्कोप जैसी कोई चीज़ नहीं (ईएस 5; ईएस 6 परिचय let)

    ए।

    var a = 1;
    
    function four() {
      if (true) {
        var a = 4;
      }
    
      alert(a); // alerts '4', not the global value of '1'
    }
    

    ख।

    var a = 1;
    
    function one() {
      if (true) {
        let a = 4;
      }
    
      alert(a); // alerts '1' because the 'let' keyword uses block scoping
    }
    
  4. मध्यम: वस्तु गुण

    var a = 1;
    
    function Five() {
      this.a = 5;
    }
    
    alert(new Five().a); // alerts '5'
    
  5. उन्नत: समापन

    var a = 1;
    
    var six = (function() {
      var a = 6;
    
      return function() {
        // JavaScript "closure" means I have access to 'a' in here,
        // because it is defined in the function in which I was defined.
        alert(a); // alerts '6'
      };
    })();
    
  6. उन्नत: प्रोटोटाइप-आधारित स्कोप रिज़ॉल्यूशन

    var a = 1;
    
    function seven() {
      this.a = 7;
    }
    
    // [object].prototype.property loses to
    // [object].property in the lookup chain. For example...
    
    // Won't get reached, because 'a' is set in the constructor above.
    seven.prototype.a = -1;
    
    // Will get reached, even though 'b' is NOT set in the constructor.
    seven.prototype.b = 8;
    
    alert(new seven().a); // alerts '7'
    alert(new seven().b); // alerts '8'
    

  7. वैश्विक + स्थानीय: एक अतिरिक्त जटिल मामला

    var x = 5;
    
    (function () {
        console.log(x);
        var x = 10;
        console.log(x); 
    })();
    

    यह प्रिंट करेगा undefined तथा 10 बजाय 5 तथा 10 चूंकि जावास्क्रिप्ट हमेशा दायरे के शीर्ष पर परिवर्तनीय घोषणाएं (प्रारंभिकरण नहीं) चलाता है, जिससे कोड बराबर होता है:

    var x = 5;
    
    (function () {
        var x;
        console.log(x);
        x = 10;
        console.log(x); 
    })();
    
  8. खंड-स्कोप्ड चर पकड़ो

    var e = 5;
    console.log(e);
    try {
        throw 6;
    } catch (e) {
        console.log(e);
    }
    console.log(e);
    

    यह प्रिंट करेगा 5, 6, 5। पकड़ खंड के अंदर e वैश्विक और स्थानीय चर छाया। लेकिन यह विशेष दायरा केवल पकड़े गए चर के लिए है। यदि आप लिखते हैं var f; कैच क्लॉज के अंदर, फिर यह वही है जैसा आपने कोशिश-पकड़ ब्लॉक से पहले या बाद में परिभाषित किया था।


2267
2018-02-01 08:58



व्यापक होने के करीब भी नहीं, लेकिन यह शायद जावास्क्रिप्ट स्कोप चालों का जरूरी सेट है जिसे किसी को भी प्रभावी रूप से आधुनिक जावास्क्रिप्ट पढ़ने की आवश्यकता है। - Triptych
एक उच्च मूल्यांकन किया गया जवाब, यकीन नहीं क्यों। यह उचित स्पष्टीकरण के बिना उदाहरणों का एक गुच्छा है, फिर स्कोप श्रृंखला (यानी परिवर्तनीय संकल्प) के साथ प्रोटोटाइप विरासत (यानी संपत्ति संकल्प) को भ्रमित करने लगता है। गुंजाइश और संपत्ति संकल्प का एक व्यापक (और सटीक) स्पष्टीकरण comp.lang.javascript में है एफएक्यू नोट्स। - RobG
@RobG यह अत्यधिक मूल्यांकन किया गया है क्योंकि यह प्रोग्रामर की एक विस्तृत श्रृंखला के लिए उपयोगी और समझदार है, इसके बावजूद मामूली catachresis। आपके द्वारा पोस्ट किया गया लिंक, कुछ पेशेवरों के लिए उपयोगी होने पर, आज जावास्क्रिप्ट लिखने वाले अधिकांश लोगों के लिए समझ में नहीं आता है। उत्तर संपादित करके किसी भी नामकरण मुद्दों को ठीक करने के लिए स्वतंत्र महसूस करें। - Triptych
@ triptych-I केवल मामूली चीज़ों को ठीक करने के लिए उत्तर संपादित करता है, प्रमुख नहीं। "संपत्ति" में "दायरा" बदलना त्रुटि को ठीक करेगा, लेकिन बिना किसी स्पष्ट भेद के मिश्रण विरासत और दायरे के मुद्दे को नहीं। - RobG
यदि आप बाहरी दायरे में एक चर परिभाषित करते हैं, और फिर एक if कथन एक ही नाम के साथ फ़ंक्शन के अंदर एक चर परिभाषित करता है, भले ही वह शाखा न पहुंच जाए यह फिर से परिभाषित किया गया है। एक उदाहरण - jsfiddle.net/3CxVm - Chris S


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

स्कोप चेन में एक तत्व मूल रूप से एक पॉइंटर के साथ अपने माता-पिता के लिए एक नक्शा है।

एक चर को हल करते समय, जावास्क्रिप्ट सबसे निचले दायरे से शुरू होता है और बाहर की खोज करता है।


219
2018-02-01 08:35



स्कोप चेन [स्मृति] के लिए एक और शब्द हैं बंद... जावास्क्रिप्ट में सीखने / प्राप्त करने के लिए यहां पढ़ने वाले लोगों के लिए। - New Alexandria


विश्व स्तर पर घोषित वैरिएबल का वैश्विक दायरा है। किसी फ़ंक्शन के भीतर घोषित वेरिएबल्स को उस फ़ंक्शन पर स्कॉप्ड किया जाता है, और उसी नाम के छाया वैश्विक चर शामिल होते हैं।

(मुझे यकीन है कि कई subtleties हैं कि असली जावास्क्रिप्ट प्रोग्रामर अन्य उत्तरों में इंगित करने में सक्षम हो जाएगा। विशेष रूप से मैं पार आया यह पन्ना वास्तव में क्या के बारे में this किसी भी समय मतलब है। उम्मीद है कि यह अधिक प्रारंभिक लिंक यद्यपि शुरू करने के लिए पर्याप्त है।)


93
2018-02-01 08:31



मैं इस सवाल का जवाब देना भी डरता हूं। एक असली जावास्क्रिप्ट प्रोग्रामर के रूप में, मुझे पता है कि जवाब हाथ से कितनी जल्दी हो सकता है। अच्छा लेख - Triptych
@Triptych: मुझे पता है कि हाथ से बाहर निकलने वाली चीजों के बारे में आपका क्या मतलब है, लेकिन कृप्या वैसे भी एक जवाब जोड़ें। मुझे ऊपर कुछ खोज करने से उपरोक्त मिला ... वास्तविक अनुभव वाले किसी व्यक्ति द्वारा लिखित उत्तर है सीमा अच्छा बनने के लिए। कृपया मेरे किसी भी उत्तर को सही करें जो निश्चित रूप से गलत है! - Jon Skeet
किसी भी तरह जॉन स्कीट स्टैक ओवरफ्लो पर मेरे सबसे लोकप्रिय उत्तर के लिए ज़िम्मेदार है। - Triptych


पुरानी स्कूल जावास्क्रिप्ट

पारंपरिक रूप से, जावास्क्रिप्ट में वास्तव में केवल दो प्रकार के दायरे होते हैं:

  1. वैश्विक कार्यक्षेत्र : आवेदन की शुरुआत से, वैरिएबल पूरे एप्लिकेशन में जाना जाता है (*)
  2. कार्यात्मक दायरा : चर के भीतर जाना जाता है कार्यक्रम उन्हें समारोह की शुरुआत से घोषित किया जाता है (*)

मैं इस पर विस्तार नहीं करूंगा, क्योंकि अंतर को समझाते हुए पहले से ही कई अन्य उत्तर हैं।


आधुनिक जावास्क्रिप्ट

सबसे हालिया जावास्क्रिप्ट चश्मा अब तीसरे दायरे की भी अनुमति दें:

  1. ब्लॉक स्कोप : चर के भीतर जाना जाता है खंडउन्हें घोषित किया जाता है, उस क्षण से जब उन्हें घोषित किया जाता है (**)

मैं ब्लॉक स्कोप चर कैसे बना सकता हूं?

पारंपरिक रूप से, आप इस तरह के अपने चर बनाते हैं:

var myVariable = "Some text";

ब्लॉक स्कोप चर इस तरह बनाए गए हैं:

let myVariable = "Some text";

तो कार्यात्मक दायरे और ब्लॉक गुंजाइश के बीच क्या अंतर है?

कार्यात्मक दायरे और ब्लॉक स्कोप के बीच अंतर को समझने के लिए, निम्न कोड पर विचार करें:

// i IS NOT known here
// j IS NOT known here
// k IS known here, but undefined
// l IS NOT known here

function loop(arr) {
    // i IS known here, but undefined
    // j IS NOT known here
    // k IS known here, but has a value only the second time loop is called
    // l IS NOT known here

    for( var i = 0; i < arr.length; i++ ) {
        // i IS known here, and has a value
        // j IS NOT known here
        // k IS known here, but has a value only the second time loop is called
        // l IS NOT known here
    };

    // i IS known here, and has a value
    // j IS NOT known here
    // k IS known here, but has a value only the second time loop is called
    // l IS NOT known here

    for( let j = 0; j < arr.length; j++ ) {
        // i IS known here, and has a value
        // j IS known here, and has a value
        // k IS known here, but has a value only the second time loop is called
        // l IS NOT known here
    };

    // i IS known here, and has a value
    // j IS NOT known here
    // k IS known here, but has a value only the second time loop is called
    // l IS NOT known here
}

loop([1,2,3,4]);

for( var k = 0; k < arr.length; k++ ) {
    // i IS NOT known here
    // j IS NOT known here
    // k IS known here, and has a value
    // l IS NOT known here
};

for( let l = 0; l < arr.length; l++ ) {
    // i IS NOT known here
    // j IS NOT known here
    // k IS known here, and has a value
    // l IS known here, and has a value
};

loop([1,2,3,4]);

// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS NOT known here

यहां, हम देख सकते हैं कि हमारे चर j केवल लूप के लिए पहले में जाना जाता है, लेकिन पहले और बाद में नहीं। फिर भी, हमारे चर i पूरे समारोह में जाना जाता है।

साथ ही, मान लें कि ब्लॉक स्कॉप्ड वैरिएबल घोषित होने से पहले ज्ञात नहीं हैं क्योंकि वे फट नहीं गए हैं। आपको उसी ब्लॉक के भीतर एक ही ब्लॉक स्कोप्ड वैरिएबल को फिर से चलाने की अनुमति नहीं है। यह ब्लॉक स्कोप्ड वेरिएबल्स को वैश्विक स्तर पर या कार्यात्मक रूप से स्कॉप्ड चर के मुकाबले कम त्रुटि प्रवण बनाता है, जो फहराया जाता है और जो कई घोषणाओं के मामले में कोई त्रुटि उत्पन्न नहीं करता है।


क्या आज ब्लॉक स्कोप चर का उपयोग करना सुरक्षित है?

चाहे आज उपयोग करना सुरक्षित है या नहीं, आपके पर्यावरण पर निर्भर करता है:

  • यदि आप सर्वर-साइड जावास्क्रिप्ट कोड लिख रहे हैं (Node.js), आप सुरक्षित रूप से उपयोग कर सकते हैं let बयान।

  • यदि आप क्लाइंट-साइड जावास्क्रिप्ट कोड लिख रहे हैं और एक ट्रांसलेटर का उपयोग करें (जैसे Traceur), आप सुरक्षित रूप से उपयोग कर सकते हैं let बयान, हालांकि आपका कोड प्रदर्शन के संबंध में इष्टतम लेकिन कुछ भी होने की संभावना है।

  • यदि आप क्लाइंट-साइड जावास्क्रिप्ट कोड लिख रहे हैं और एक ट्रांसलेटर का उपयोग नहीं करते हैं, तो आपको ब्राउज़र समर्थन पर विचार करने की आवश्यकता है।

    आज, 23 फरवरी 2016, ये कुछ ब्राउज़र हैं जो या तो समर्थन नहीं करते हैं let या केवल आंशिक समर्थन है:

    • इंटरनेट एक्सप्लोरर 10 और नीचे (कोई समर्थन नहीं)
    • फ़ायरफ़ॉक्स 43 और नीचे (कोई समर्थन नहीं)
    • सफारी 9 और नीचे (कोई समर्थन नहीं)
    • ओपेरा मिनी 8 और नीचे (कोई समर्थन नहीं)
    • एंड्रॉइड ब्राउज़र 4 और नीचे (कोई समर्थन नहीं)
    • ओपेरा 36 और नीचे (आंशिक समर्थन)
    • क्रोम 51 और नीचे (आंशिक समर्थन)

enter image description here


ब्राउज़र समर्थन का ट्रैक कैसे रखें

एक ब्राउज़र के समर्थन के लिए एक अद्यतित अवलोकन के लिए let इस जवाब को पढ़ने के समय बयान, देखें इस Can I Use पृष्ठ


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

(**) ब्लॉक स्कॉप्ड वेरिएबल नहीं फंस गए हैं


55
2018-02-23 18:51



"ज्ञात नहीं है" भ्रामक है, क्योंकि होस्टिंग के कारण वेरिएबल घोषित किया जाता है। - Oriol
उपर्युक्त उदाहरण भ्रामक है, चर के बाहर चर 'i' और 'j' ज्ञात नहीं हैं। 'चलो' चर के पास उस विशेष ब्लॉक में केवल ब्लॉक के बाहर नहीं है। चलो अन्य फायदे भी हैं, आप वैरिएबल को दोबारा नहीं बदल सकते हैं और यह लेक्सिकल स्कोप है। - zakir
@ ओरियल: आखिर में मेरा जवाब और पता उठाने में सुधार हुआ। मेरे जवाब को इंगित करने के लिए धन्यवाद आवश्यक सुधार। मैंने कुछ अन्य सुधार भी किए हैं। - John Slegers
@ जोनस्चनेडर: सही! जहां मैं "पुराना स्कूल जावास्क्रिप्ट" कहता हूं, मैं वास्तव में ईसीएमएस्क्रिप्ट 5 के बारे में बात कर रहा हूं और जहां मैं "आधुनिक जावास्क्रिप्ट" का जिक्र कर रहा हूं, मैं ईसीएमएस्क्रिप्ट 6 (उर्फ ईसीएमएस्क्रिप्ट 2015) ले रहा हूं। मुझे नहीं लगता था कि यहां वास्तव में विस्तार करना महत्वपूर्ण था, हालांकि, अधिकांश लोग सिर्फ जानना चाहते हैं (1) ब्लॉक स्कोप और कार्यात्मक दायरे के बीच क्या अंतर है, (2) कौन से ब्राउजर ब्लॉक स्कोप का समर्थन करते हैं और (3) क्या वे आज भी जिस परियोजना पर काम कर रहे हैं, उसके लिए ब्लॉक स्कोप का उपयोग करना सुरक्षित है या नहीं। इसलिए मैंने उन मुद्दों को संबोधित करने पर अपना जवाब केंद्रित किया। - John Slegers
@ जोनस्चनेडर: (जारी) फिर भी, मैंने अभी उन लोगों के लिए ES6 / ES2015 पर एक स्मैशिंग पत्रिका लेख का एक लिंक जोड़ा है जो पिछले कुछ वर्षों के दौरान जावास्क्रिप्ट में कौन सी विशेषताओं को जोड़ा गया है, इसके बारे में और जानना चाहते हैं ... हो सकता है कि "आधुनिक जावास्क्रिप्ट" के साथ मेरा क्या मतलब है। - John Slegers


यहां एक उदाहरण दिया गया है:

<script>

var globalVariable = 7; //==window.globalVariable

function aGlobal( param ) { //==window.aGlobal(); 
                            //param is only accessible in this function
  var scopedToFunction = {
    //can't be accessed outside of this function

    nested : 3 //accessible by: scopedToFunction.nested
  };

  anotherGlobal = {
    //global because there's no `var`
  }; 

}

</script>

आप बंद करने की जांच करना चाहते हैं, और उन्हें कैसे उपयोग करना है निजी सदस्य


35
2018-02-01 08:48





कुंजी, जैसा कि मैं इसे समझता हूं, यह है कि जावास्क्रिप्ट में अधिक सामान्य सी ब्लॉक स्कोपिंग बनाम कार्य स्कोपिंग है।

इस विषय पर एक अच्छा लेख है।


28
2018-05-15 17:38





"जावास्क्रिप्ट 1.7" (मोज़िला का जावास्क्रिप्ट का विस्तार) में कोई ब्लॉक-स्कोप वैरिएबल घोषित कर सकता है let बयान:

 var a = 4;
 let (a = 3) {
   alert(a); // 3
 }
 alert(a);   // 4

23
2018-04-06 11:19



हाँ, लेकिन क्या इसका उपयोग सुरक्षित है? मेरा मतलब है कि यदि मैं अपना कोड वेबकिट में चलाऊंगा तो क्या मैं वास्तव में इस कार्यान्वयन का चयन करूंगा? - Igor Ganapolsky
@ पायथन: नहीं, वेबकिट का समर्थन नहीं करता है let। - kennytm
मुझे लगता है कि इसके लिए एकमात्र वैध उपयोग होगा यदि आप जानते थे कि सभी क्लाइंट एक कंपनी आंतरिक प्रणाली के लिए मोज़िला ब्राउज़र का उपयोग करेंगे। - GazB
या यदि आप एक्सयूएल फ्रेमवर्क का उपयोग कर प्रोग्रामिंग कर रहे हैं, तो मोज़िला का इंटरफेस फ्रेमवर्क जहां आप सीएसएस, एक्सएमएल और जावास्क्रिप्ट का उपयोग करते हैं। - Gerard ONeill
@GazB भी यह एक भयानक विचार है! तो आज आप जानते हैं कि आपके ग्राहक मोज़िला का उपयोग कर रहे हैं तो बाहर एक नया ज्ञापन आता है जिसमें कहा गया है कि अब वे कुछ और उपयोग कर रहे हैं। अर्थात। कारण हमारे वेतन प्रणाली बेकार है ... आपको IE8 का उपयोग करना चाहिए और कभी भी IE9 या IE10 या फ़ायरफ़ॉक्स या क्रोम का उपयोग नहीं करना चाहिए क्योंकि यह काम नहीं कर रहा है ... - buzzsawddog


मूल रूप से डिजाइन किए जाने पर जावास्क्रिप्ट में स्कॉइंग का विचार ब्रेंडन ईच से आया था हाइपर कार्ड भाषा का अंकन HyperTalk

इस भाषा में, डिस्प्ले इंडेक्स कार्ड के ढेर के समान किए गए थे। पृष्ठभूमि के रूप में संदर्भित एक मास्टर कार्ड था। यह पारदर्शी था और नीचे कार्ड के रूप में देखा जा सकता है। इस बेस कार्ड पर किसी भी सामग्री को इसके ऊपर रखे कार्ड के साथ साझा किया गया था। शीर्ष पर रखे गए प्रत्येक कार्ड की अपनी सामग्री थी जो पिछले कार्ड पर प्राथमिकता लेती थी, लेकिन वांछित होने पर अभी भी पूर्व कार्ड तक पहुंच थी।

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

यह बाध्यकारी युक्त वस्तु को इंगित करेगा। कभी-कभी स्कॉप्स या निष्पादन संदर्भ में ऑब्जेक्ट बदलने के बिना परिवर्तन होता है, जैसे एक घोषित फ़ंक्शन में जहां ऑब्जेक्ट हो सकता है window या एक कन्स्ट्रक्टर समारोह।

इन निष्पादन संदर्भों को किसी भी समय नियंत्रण स्थानांतरित किया जाता है। कोड निष्पादित होने पर नियंत्रण स्थानांतरित होता है, और यह मुख्य रूप से फ़ंक्शन निष्पादन से किया जाता है।

तो यह तकनीकी स्पष्टीकरण है। अभ्यास में, जावास्क्रिप्ट में याद रखना महत्वपूर्ण है

  • स्कॉप्स तकनीकी रूप से "निष्पादन संदर्भ" हैं
  • संदर्भ उन वातावरणों का एक ढेर बनाते हैं जहां चर संग्रहित होते हैं
  • ढेर के शीर्ष को प्राथमिकता दी जाती है (नीचे वैश्विक संदर्भ है)
  • प्रत्येक कार्य निष्पादन संदर्भ बनाता है (लेकिन यह हमेशा बाध्यकारी नहीं है)

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

मैं) बाहरी संदर्भ। इसमें एक = 1 का एक परिवर्तनीय वातावरण है
ii) आईआईएफई संदर्भ, इसमें एक = 1 का एक व्याख्यात्मक वातावरण है, लेकिन एक = 6 का एक परिवर्तनीय वातावरण जो ढेर में प्राथमिकता लेता है
iii) लौटा कार्य संदर्भ, इसमें एक = 6 का एक व्याख्यात्मक वातावरण है और यह कॉल किए जाने पर अलर्ट में संदर्भित मान है।

enter image description here


18
2017-09-14 20:29





1) एक वैश्विक दायरा, एक समारोह का दायरा है, और साथ में पकड़ और पकड़ने के लिए। चर के लिए सामान्य रूप से कोई 'ब्लॉक' स्तर का दायरा नहीं है - साथ और पकड़ बयान उनके ब्लॉक में नाम जोड़ते हैं।

2) वैश्विक दायरे के लिए सभी तरह से कार्यों द्वारा घोंसला घोंसला जाता है।

3) गुण प्रोटोटाइप श्रृंखला के माध्यम से हल करके हल कर रहे हैं। विवरण के साथ ब्लॉक के साथ परिभाषित शब्दावली क्षेत्र में वस्तु संपत्ति नाम लाता है।

संपादित करें: ECMAAScript 6 (सद्भावना) को समर्थन देने के लिए speced किया गया है, और मुझे पता है क्रोम एक 'सद्भाव' ध्वज की अनुमति देता है, तो शायद यह इसका समर्थन करता है ..

चलो ब्लॉक स्तर स्कोपिंग के लिए एक समर्थन होगा, लेकिन इसे करने के लिए आपको कीवर्ड का उपयोग करना होगा।

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

 //chrome (v8)

 var a = { 'test1':'test1val' }
 test1   // error not defined
 with (a) { var test1 = 'replaced' }
 test1   // undefined
 a       // a.test1 = 'replaced'

संपादित करें: स्पष्टीकरण उदाहरण:

test1 ब्लॉक के साथ scoped है, लेकिन a.test1 के लिए aliased है। 'Var test1' ऊपरी अक्षीय संदर्भ (फ़ंक्शन, या वैश्विक) में एक नया चर परीक्षण 1 बनाता है, जब तक कि यह एक की संपत्ति न हो - जो यह है।

ओह! 'साथ' का उपयोग करके सावधान रहें - जैसे वैर एक नोप है यदि चर पहले से ही फ़ंक्शन में परिभाषित किया गया है, तो यह ऑब्जेक्ट से आयात किए गए नामों के संबंध में एक नोप भी है! पहले से परिभाषित नाम पर थोड़ा सिर इसे अधिक सुरक्षित बना देगा। इस वजह से मैं व्यक्तिगत रूप से कभी भी इसका उपयोग नहीं करूंगा।


16
2017-10-25 00:41



यहां कुछ गलतियां हैं, क्योंकि एक जावास्क्रिप्ट में ब्लॉक स्कोपिंग के रूप हैं। - Benjamin Gruenbaum
मेरे कान (आंखें) खुले हैं, बेंजामिन - ऊपर दिए गए मेरे बयान हैं कि मैं जावास्क्रिप्ट स्कोपिंग का इलाज कैसे कर रहा हूं, लेकिन वे कल्पना पढ़ने पर आधारित नहीं हैं। और मुझे आशा है कि आप इस कथन का जिक्र नहीं कर रहे हैं (जो वस्तु स्कोपिंग का एक रूप है), या मोज़िला के विशेष 'चलो' वाक्यविन्यास। - Gerard ONeill
कुंआ, with बयान है ब्लॉक स्कोपिंग का एक रूप लेकिन catch खंड एक बहुत आम रूप हैं (मजेदार तथ्य, v8 उपकरण catch के साथ with) - यह जावास्क्रिप्ट में स्वयं स्कोपिंग का एकमात्र रूप है (यानी, फ़ंक्शन, ग्लोबल, कोशिश / पकड़, और उनके डेरिवेटिव्स), हालांकि होस्ट वातावरण में स्कोपिंग के अलग-अलग विचार हैं - उदाहरण के लिए ब्राउज़र में इनलाइन ईवेंट और नोडजेएस वीएम मॉड्यूल। - Benjamin Gruenbaum
बेंजामिन - जो मैं देख सकता हूं, दोनों ही ऑब्जेक्ट को केवल वर्तमान दायरे (और इस प्रकार गुणों) में पेश करते हैं, लेकिन फिर संबंधित ब्लॉक समाप्त होने के बाद, चर रीसेट हो जाते हैं। लेकिन उदाहरण के लिए, एक पकड़ में पेश किए गए एक नए चर के पास संलग्न कार्य / विधि का दायरा होगा। - Gerard ONeill
जो वास्तव में ब्लॉक स्कोपिंग का मतलब है :) - Benjamin Gruenbaum


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

इस सुविधा को आजमाएं:

यहां एक डेमो देखें:

यहां कोड देखें:

वर्तमान में यह सुविधा 16 नेस्टेड फ़ंक्शंस की गहराई के लिए समर्थन प्रदान करती है, लेकिन वर्तमान में वैश्विक चर रंग नहीं है।


9
2018-03-21 17:31



फ़ायरफ़ॉक्स 26 के साथ मेरे लिए काम नहीं करता है। मैं कोड पेस्ट करता हूं या फ़ाइल लोड करता हूं, निष्पादित क्लिक करता हूं और कुछ भी नहीं होता है। - Michael Lemke


जावास्क्रिप्ट में केवल दो प्रकार का दायरा है:

  1. वैश्विक कार्यक्षेत्र : वैश्विक खिड़की के स्तर के दायरे के अलावा कुछ भी नहीं है। यहाँ, पूरे आवेदन में परिवर्तनीय उपस्थिति।
  2. कार्यात्मक दायरा : वैरिएबल के साथ एक समारोह के भीतर घोषित किया गया var कीवर्ड में कार्यात्मक दायरा है।

जब भी कोई फ़ंक्शन कहा जाता है, तो एक चरणीय स्कोप ऑब्जेक्ट बनाया जाता है (और स्कोप चेन में शामिल किया जाता है) जिसके बाद जावास्क्रिप्ट में चर होते हैं।

        a = "global";
         function outer(){ 
              b = "local";
              console.log(a+b); //"globallocal"
         }
outer();

स्कोप श्रृंखला ->

  1. खिड़की का स्तर - a तथा outer कार्य स्कोप श्रृंखला में शीर्ष स्तर पर हैं।
  2. जब बाहरी समारोह एक नया कहा जाता है variable scope object(और स्कोप श्रृंखला में शामिल) चर के साथ जोड़ा गया b इसके अंदर।

अब जब एक चर a इसकी आवश्यकता है कि यह सबसे पहले निकटतम चर के दायरे की खोज करे और यदि वैरिएबल वैरिएबल स्कोप श्रृंखला के अगले ऑब्जेक्ट में स्थानांतरित नहीं होता है। इस मामले में विंडो स्तर है।


8
2017-09-21 20:44



निश्चित नहीं है कि यह स्वीकार्य उत्तर क्यों नहीं है। वास्तव में केवल कार्यात्मक दायरा है (ईसीएमए 6 से पहले कोई "स्थानीय दायरा" नहीं था) और वैश्विक बाइंडिंग - texasbruce