javascript ES6 में लेट या कास्ट के साथ घोषित चर नहीं हैं?




ecmascript-6 const (4)

मैं थोड़ी देर के लिए ईएस 6 के साथ खेल रहा हूं और मैंने देखा कि वेरिएबल के साथ घोषित किए गए वेरिएबल को उम्मीद के मुताबिक फहराया गया है ...

console.log(typeof name); // undefined
var name = "John";

... let या const साथ घोषित चर को फहराने के साथ कुछ समस्याएं हैं:

console.log(typeof name); // ReferenceError
let name = "John";

तथा

console.log(typeof name); // ReferenceError
const name = "John";

इसका मतलब यह है कि let या const साथ घोषित चर नहीं फहराया जाता है? यहाँ वास्तव में क्या हो रहा है? क्या इस मामले में कोई अंतर और अंतर है?

https://code.i-harness.com


@thefourtheye यह कहने में सही है कि इन चरों को घोषित किए जाने से पहले एक्सेस नहीं किया जा सकता है । हालाँकि, यह उससे थोड़ा अधिक जटिल है।

क्या चर या const घोषित नहीं किए गए हैं? यहाँ वास्तव में क्या हो रहा है?

सभी घोषणाएँ ( var , let , const , function , function* , class ) को जावास्क्रिप्ट में "फहराया" जाता है। इसका अर्थ है कि यदि किसी नाम को किसी दायरे में घोषित किया जाता है, तो उस दायरे में पहचानकर्ता हमेशा उस विशेष चर का संदर्भ देगा:

x = "global";
// function scope:
(function() {
    x; // not "global"

    var/let/… x;
}());
// block scope (not for `var`s):
{
    x; // not "global"

    let/const/… x;
}

यह फ़ंक्शन और ब्लॉक स्कैप्स 1 के लिए सच है।

var / function / function* डिक्लेरेशन और let / const / class डिक्लेरेशन के बीच का अंतर इनिशियलाइजेशन है
पूर्व को undefined या जनरेटर (जनरेटर) फ़ंक्शन के साथ आरंभीकृत किया जाता है, जब बाइंडिंग गुंजाइश के शीर्ष पर बनाई जाती है। लेक्सिक रूप से घोषित चर हालांकि अनैतिक रूप से बने रहते हैं। इसका मतलब है कि जब आप इसे एक्सेस करने का प्रयास करते हैं तो एक ReferenceError अपवाद को फेंक दिया जाता है। यह केवल आरंभिक रूप से प्राप्त होगा जब let / const / class स्टेटमेंट का मूल्यांकन किया जाता है, इससे पहले कि सब कुछ (ऊपर) जिसे टेम्पोरल डेड ज़ोन कहा जाता है।

x = y = "global";
(function() {
    x; // undefined
    y; // Reference error: y is not defined

    var x = "local";
    let y = "local";
}());

ध्यान दें कि let y; एक let y; स्टेटमेंट वेरिएबल को undefined साथ undefined जैसे let y = undefined; होगा।

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

क्या इस मामले में कोई अंतर और अंतर है?

नहीं, वे वही काम करते हैं जहाँ तक फहराना माना जाता है। उनके बीच एकमात्र अंतर यह है कि एक const चींटी होनी चाहिए और केवल घोषणा के प्रारंभिक भाग में सौंपी जा सकती है ( const one = 1; दोनों const one; और बाद में one = 2 तरह पुन: असाइनमेंट अमान्य हैं)।

1: var घोषणाएं अभी भी केवल फ़ंक्शन स्तर पर काम कर रही हैं, निश्चित रूप से


ECMAScript 6 (ECMAScript 2015) के विनिर्देशन को let , और घोषणाएं अनुभाग,

वैरिएबल तब बनाए जाते हैं जब उनके लेक्सिकल एनवायरनमेंट को त्वरित किया जाता है लेकिन किसी भी तरह से तब तक एक्सेस नहीं किया जा सकता है जब तक कि वेरिएबल की लेक्सिकलबाइंडिंग का मूल्यांकन नहीं किया जाता है

इसलिए, आपके प्रश्न का उत्तर देने के लिए, हां, const let और जमा करना लेकिन आप वास्तविक घोषणा से पहले उन्हें एक्सेस नहीं कर सकते हैं।


MDN वेब डॉक्स से:

ECMAScript 2015 में, let और const को उत्कीर्ण किया गया है लेकिन आरंभिक नहीं। वेरिएबल डिक्लेरेशन के रिजल्ट से पहले ब्लॉक में वेरिएबल को रेफरेंस में रिफर कर देता है क्योंकि डिक्लेरेशन प्रोसेस होने तक ब्लॉक की शुरुआत से वेरिएबल "टेम्परेरी डेड जोन" में होता है।

console.log(x); // ReferenceError
let x = 3;

ES6 Let वेरिएबल्स को प्रस्तुत करता है जो block level scoping साथ आता है। ES5 तक हमारे पास block level scoping नहीं थी, इसलिए ब्लॉक के अंदर घोषित किए गए चर हमेशा फ़ंक्शन स्तर के स्कूपिंग के लिए hoisted जाते हैं।

मूल रूप से Scope तात्पर्य है कि आपके कार्यक्रम में आपके चर कहाँ दिखाई देते हैं, जो यह निर्धारित करता है कि आपको उन चर का उपयोग करने की अनुमति है जहाँ आपने घोषित किया है। ES5 हमारे पास global scope,function scope and try/catch scope , ES6 साथ हम लेट का उपयोग करके ब्लॉक लेवल स्कूपिंग भी प्राप्त करते हैं।

  • जब आप वैरिएबल के साथ एक वैरिएबल को परिभाषित करते हैं, तो यह उस क्षण से संपूर्ण फ़ंक्शन को परिभाषित करता है, जिसे वह परिभाषित करता है।
  • जब आप एक वैरिएबल को परिभाषित करते हैं let स्टेटमेंट के साथ इसे केवल उस ब्लॉक में जाना जाता है जिसे यह परिभाषित किया गया है।

     function doSomething(arr){
         //i is known here but undefined
         //j is not known here
    
         console.log(i);
         console.log(j);
    
         for(var i=0; i<arr.length; i++){
             //i is known here
         }
    
         //i is known here
         //j is not known here
    
         console.log(i);
         console.log(j);
    
         for(let j=0; j<arr.length; j++){
             //j is known here
         }
    
         //i is known here
         //j is not known here
    
         console.log(i);
         console.log(j);
     }
    
     doSomething(["Thalaivar", "Vinoth", "Kabali", "Dinesh"]);

यदि आप कोड चलाते हैं, तो आप देख सकते हैं कि चर j केवल loop में जाना जाता है और पहले और बाद में नहीं। फिर भी, हमारे वेरिएबल i को entire function में उस क्षण से जाना जाता है, जिस दिन इसे परिभाषित किया गया है।

एक और बढ़िया फायदा यह है कि इसे एक नए संदर्भ का माहौल बनाने के साथ-साथ एक पुराने संदर्भ को रखने के बजाय नए मूल्य को बांधता है।

for(var i=1; i<6; i++){
   setTimeout(function(){
      console.log(i);
   },1000)
}

for(let i=1; i<6; i++){
   setTimeout(function(){
      console.log(i);
   },1000)
}

लूप के for पहला हमेशा अंतिम मान को प्रिंट करता है, साथ let यह एक नया दायरा बनाता है और ताजा मानों को 1, 2, 3, 4, 5 प्रिंट करता है।

constants आकर, यह मूल रूप से काम करने देता constants , एकमात्र अंतर यह है कि उनके मूल्य को बदला नहीं जा सकता है। स्थिरांक में उत्परिवर्तन की अनुमति है लेकिन पुनर्मूल्यांकन की अनुमति नहीं है।

const foo = {};
foo.bar = 42;
console.log(foo.bar); //works

const name = []
name.push("Vinoth");
console.log(name); //works

const age = 100;
age = 20; //Throws Uncaught TypeError: Assignment to constant variable.

console.log(age);

यदि कोई स्थिरांक किसी object को संदर्भित करता है, तो यह हमेशा object को संदर्भित करेगा लेकिन object स्वयं बदला जा सकता है (यदि यह परिवर्तनशील है)। यदि आपको कोई अपरिवर्तनीय object , तो आप Object.freeze([]) उपयोग कर सकते हैं





hoisting