Jaka jest różnica między " let " a "var"?

ECMAScript 6 wprowadził oświadczenie let .

Słyszałem, że jest opisana jako zmienna local, ale nadal nie jestem pewien, jak zachowuje się inaczej niż słowo kluczowe var.

Jakie są różnice?. Kiedy należy użyć let zamiast var?

Author: Akash Kumar Verma, 2009-04-17

30 answers

Zasady ustalania zakresu

Główną różnicą są zasady ustalania zakresu. Zmienne zadeklarowane przez słowo kluczowe var mają zasięg do natychmiastowego ciała funkcji (stąd zakres funkcji), podczas gdy zmienne let mają zasięg do natychmiastowego zamykającego blok oznaczony przez { } (stąd zakres bloku).

function run() {
  var foo = "Foo";
  let bar = "Bar";

  console.log(foo, bar); // Foo Bar

  {
    var moo = "Mooo"
    let baz = "Bazz";
    console.log(moo, baz); // Mooo Bazz
  }

  console.log(moo); // Mooo
  console.log(baz); // ReferenceError
}

run();

Powodem, dla którego słowo kluczowe let zostało wprowadzone do języka był zakres funkcji, jest mylące i było jednym z głównych źródeł błędów w JavaScript.

Spójrz na ten przykład z kolejne pytanie stoskoverflow :

var funcs = [];
// let's create 3 functions
for (var i = 0; i < 3; i++) {
  // and store them in funcs
  funcs[i] = function() {
    // each should log its value.
    console.log("My value: " + i);
  };
}
for (var j = 0; j < 3; j++) {
  // and now let's run each one to see
  funcs[j]();
}

My value: 3 było wysyłane do konsoli za każdym razem, gdy wywoływano funcs[j]();, ponieważ funkcje anonimowe były powiązane z tą samą zmienną.

Ludzie musieli tworzyć natychmiast wywołane funkcje, aby przechwycić poprawną wartość z pętli, ale to również było trudne.

Podnoszenie

Podczas gdy zmienne zadeklarowane za pomocą słowa kluczowego varpodniesione (zainicjalizowane za pomocą undefined przed uruchomieniem kodu), co oznacza, że są dostępne w ich zasięg jeszcze przed ogłoszeniem:

function run() {
  console.log(foo); // undefined
  var foo = "Foo";
  console.log(foo); // Foo
}

run();

let zmienne nie są inicjowane, dopóki ich definicja nie zostanie oceniona. Dostęp do nich przed inicjalizacją skutkuje ReferenceError. Zmienna powinna znajdować się w "temporal dead zone" od początku bloku do momentu rozpoczęcia procesu inicjalizacji.

function checkHoisting() {
  console.log(foo); // ReferenceError
  let foo = "Foo";
  console.log(foo); // Foo
}

checkHoisting();

Tworzenie globalnej właściwości obiektu

Na najwyższym poziomie, let, w przeciwieństwie do var, nie tworzy właściwości na globalnym obiekt:

var foo = "Foo";  // globally scoped
let bar = "Bar"; // globally scoped

console.log(window.foo); // Foo
console.log(window.bar); // undefined

Redeklaracja

W trybie strict, var pozwoli Ci ponownie zadeklarować tę samą zmienną w tym samym zakresie, podczas gdy let wyświetli błąd SyntaxError.

'use strict';
var foo = "foo1";
var foo = "foo2"; // No problem, 'foo' is replaced.

let bar = "bar1";
let bar = "bar2"; // SyntaxError: Identifier 'bar' has already been declared
 6533
Author: ThinkingStiff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-02-13 04:48:41

let może być również stosowany w celu uniknięcia problemów z zamknięciami. Wiąże świeżą wartość zamiast zachowywania starego odniesienia, jak pokazano w przykładach poniżej.

for(var i=1; i<6; i++) {
  $("#div" + i).click(function () { console.log(i); });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Clicking on each number will log to console:</p> 
<div id="div1">1</div>
<div id="div2">2</div>
<div id="div3">3</div>
<div id="div4">4</div>
<div id="div5">5</div>

Powyższy kod pokazuje klasyczny problem zamknięcia JavaScript. Odniesienie do zmiennej i jest przechowywane w zamknięciu obsługi kliknięć, zamiast rzeczywistej wartości i.

Obsługa każdego kliknięcia będzie odnosić się do tego samego obiektu, ponieważ jest tylko jeden obiekt licznika, który posiada 6, więc masz sześć na każdym kliknięciu.

Ogólnym obejściem jest zawinięcie tego w funkcję anonimową i przekazanie i jako argumentu. Takich problemów można również uniknąć teraz, używając let zamiast var, Jak pokazano w poniższym kodzie.

(testowane w Chrome i Firefox 50)

for(let i=1; i<6; i++) {
  $("#div" + i).click(function () { console.log(i); });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Clicking on each number will log to console:</p> 
<div id="div1">1</div>
<div id="div2">2</div>
<div id="div3">3</div>
<div id="div4">4</div>
<div id="div5">5</div>
 675
Author: Gurpreet Singh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-29 08:47:10

Jaka jest różnica między let A var?

  • zmienna zdefiniowana za pomocą instrukcji var jest znana na całym funkcja jest zdefiniowana w, Od początku funkcji. (*)
  • zmienna zdefiniowana za pomocą Instrukcji let jest znana tylko w blok jest zdefiniowany w, od momentu, gdy jest zdefiniowany dalej. (**)

Aby zrozumieć różnicę, rozważ następujące kod:

// 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

Tutaj widzimy, że nasza zmienna {[5] } jest znana tylko w pierwszej pętli for, ale nie przed i po. Jednak nasza zmienna i jest znana w całej funkcji.

Należy również wziąć pod uwagę, że zmienne o zasięgu blokowym nie są znane przed ich zadeklarowaniem, ponieważ nie są podnoszone. Nie można również ponownie zadeklarować tej samej zmiennej o zasięgu bloku w tym samym bloku. To sprawia, że zmienne o zasięgu blokowym są mniej podatne na błędy niż zmienne o zasięgu globalnym lub funkcjonalnym, które są podnoszone i które nie powodują błędów w przypadku wielokrotnych deklaracji.


Czy jest bezpiecznie używać let dzisiaj?

Niektórzy twierdzą, że w przyszłości będziemy używać tylko wyrażeń let i że wyrażenia var staną się przestarzałe. JavaScript guru Kyle Simpson napisał bardzo rozbudowany artykuł o tym, dlaczego uważa, że tak nie będzie.

Dzisiaj jednak na pewno tak nie jest. W rzeczywistości, potrzebujemy właściwie, aby zadać sobie pytanie, czy korzystanie z let oświadczenia jest bezpieczne. Odpowiedź na to pytanie zależy od środowiska: {]}

  • Jeśli piszesz kod JavaScript po stronie serwera (węzeł.js), możesz bezpiecznie używać let.

  • Jeśli piszesz kod JavaScript po stronie klienta i używasz transpilera opartego na przeglądarce (jak Traceur lub babel-samodzielny), możesz bezpiecznie używać let oświadczenie, jednak Twój kod prawdopodobnie nie będzie optymalny pod względem wydajności.

  • Jeśli piszesz kod JavaScript po stronie klienta i używasz transpilera opartego na węzłach (np. traceur shell script lub Babel), możesz bezpiecznie używać let. A ponieważ twoja przeglądarka będzie wiedziała tylko o transpiled code, wady wydajności powinny być ograniczone.

  • Jeśli piszesz po stronie klienta Kod JavaScript i nie używaj transpilera, musisz rozważyć obsługę przeglądarki.

    Mimo to niektóre przeglądarki nadal nie obsługują let w ogóle:

Tutaj wpisz opis obrazka


Jak śledzić obsługę przeglądarki

Aby uzyskać aktualny przegląd przeglądarek, które obsługują oświadczenie let w momencie czytania tej odpowiedzi, zobacz this Can I Use page.


(*) globalnie i funkcjonalnie zmienne mogą być inicjowane i używane przed ich zadeklarowaniem, ponieważ zmienne JavaScript są hoisted. oznacza to, że deklaracje są zawsze na szczycie zakresu.

(**) zmienne o zasięgu blokowym nie są podnoszone

 245
Author: John Slegers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55

Oto Wyjaśnienie słowa kluczowego let z kilkoma przykładami.

let działa bardzo podobnie do var. Główną różnicą jest to, że zakres zmiennej var jest całką funkcji

Ta tabela na Wikipedii pokazuje, które przeglądarki obsługują Javascript 1.7.

Zauważ, że obsługują ją tylko przeglądarki Mozilla i Chrome. IE, Safari i potencjalnie inne nie.

 153
Author: Ben S,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-24 02:52:39

W zaakceptowanej odpowiedzi brakuje punktu:

{
  let a = 123;
};

console.log(a); // ReferenceError: a is not defined
 123
Author: Lcf.vs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-14 14:13:44

let

Zakres bloku

Zmienne zadeklarowane za pomocą słowa kluczowego let są o zasięgu blokowym, co oznacza, że są dostępne tylko w bloku , w którym zostały zadeklarowane.

Na najwyższym poziomie (poza funkcją)

Na najwyższym poziomie zmienne zadeklarowane za pomocą let nie tworzą właściwości w obiekcie globalnym.

var globalVariable = 42;
let blockScopedVariable = 43;

console.log(globalVariable); // 42
console.log(blockScopedVariable); // 43

console.log(this.globalVariable); // 42
console.log(this.blockScopedVariable); // undefined

Wewnątrz funkcji

Wewnątrz funkcji (ale poza blokiem), let ma taki sam zakres jak var.

(() => {
  var functionScopedVariable = 42;
  let blockScopedVariable = 43;

  console.log(functionScopedVariable); // 42
  console.log(blockScopedVariable); // 43
})();

console.log(functionScopedVariable); // ReferenceError: functionScopedVariable is not defined
console.log(blockScopedVariable); // ReferenceError: blockScopedVariable is not defined

Wewnątrz bloku

Zmienne zadeklarowane za pomocą let wewnątrz bloku nie mogą być dostępne poza tym blokiem.

{
  var globalVariable = 42;
  let blockScopedVariable = 43;
  console.log(globalVariable); // 42
  console.log(blockScopedVariable); // 43
}

console.log(globalVariable); // 42
console.log(blockScopedVariable); // ReferenceError: blockScopedVariable is not defined

Wewnątrz pętli

Zmienne zadeklarowane przez let W pętli mogą być odwołane tylko wewnątrz tej pętli.

for (var i = 0; i < 3; i++) {
  var j = i * 2;
}
console.log(i); // 3
console.log(j); // 4

for (let k = 0; k < 3; k++) {
  let l = k * 2;
}
console.log(typeof k); // undefined
console.log(typeof l); // undefined
// Trying to do console.log(k) or console.log(l) here would throw a ReferenceError.

Pętle z zamknięciami

Jeśli użyjesz let zamiast var W PĘTLI, z każdą iteracją otrzymasz nową zmienną. Oznacza to, że można bezpiecznie używać zamknięcia wewnątrz pętla.

// Logs 3 thrice, not what we meant.
for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 0);
}

// Logs 0, 1 and 2, as expected.
for (let j = 0; j < 3; j++) {
  setTimeout(() => console.log(j), 0);
}

Temporal dead zone

Z powodu martwej strefy czasowej , zmienne zadeklarowane za pomocą let nie mogą być dostępne przed ich zadeklarowaniem. Próba zrobienia tego powoduje błąd.

console.log(noTDZ); // undefined
var noTDZ = 43;
console.log(hasTDZ); // ReferenceError: hasTDZ is not defined
let hasTDZ = 42;

No re-declaration

Nie Można zadeklarować tej samej zmiennej wiele razy za pomocą let. Nie można również zadeklarować zmiennej za pomocą let z tym samym identyfikatorem, co inna zmienna zadeklarowana za pomocą var.

var a;
var a; // Works fine.

let b;
let b; // SyntaxError: Identifier 'b' has already been declared

var c;
let c; // SyntaxError: Identifier 'c' has already been declared

const

const jest bardzo podobny do let-ma zasięg blokowy i ma TDZ. Są jednak dwie różne rzeczy.

No re-assigning

Zmienna zadeklarowana za pomocą const nie może być ponownie przypisana.

const a = 42;
a = 43; // TypeError: Assignment to constant variable.

Zauważ, że nie oznacza to, że wartość jest niezmienna. Jego właściwości nadal można zmienić.

const obj = {};
obj.a = 42;
console.log(obj.a); // 42

Jeśli chcesz mieć obiekt niezmienny, powinieneś użyć Object.freeze().

Inicjalizator jest wymagane

Zawsze musisz podać wartość podczas deklarowania zmiennej za pomocą const.

const a; // SyntaxError: Missing initializer in const declaration
 98
Author: Michał Perłakowski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-25 20:54:47

Główną różnicą jest różnica scope, podczas gdy let może być dostępny tylko wewnątrz scope jest zadeklarowany, podobnie jak w pętli for, var może być dostępny na przykład poza pętlą. Z Dokumentacji w MDN (przykłady również z MDN):

Let pozwala zadeklarować zmienne, które są ograniczone w zakresie do bloku, instrukcji lub wyrażenia, na którym jest używana. Jest to w przeciwieństwie do słowa kluczowego var, które definiuje zmienną globalnie lub lokalnie dla całej funkcji niezależnie od zakresu bloku.

Zmienne zadeklarowane przez niech mają jako swój zakres blok, w którym są zdefiniowane, jak również w dowolnych zawartych pod-blokach. W ten sposób let działa bardzo podobnie do var . Główną różnicą jest to, że zakres zmiennej var jest całką funkcji zamykającej:

function varTest() {
  var x = 1;
  if (true) {
    var x = 2;  // same variable!
    console.log(x);  // 2
  }
  console.log(x);  // 2
}

function letTest() {
  let x = 1;
  if (true) {
    let x = 2;  // different variable
    console.log(x);  // 2
  }
  console.log(x);  // 1
}`

Na najwyższym poziomie programów i funkcji, niech , w przeciwieństwie do var , nie tworzy właściwości na obiekcie globalnym. Na przykład:

var x = 'global';
let y = 'global';
console.log(this.x); // "global"
console.log(this.y); // undefined

W przypadku użycia wewnątrz bloku, ogranicz zakres zmiennej do tego bloku. Zwróć uwagę na różnicę pomiędzy var , którego zakres znajduje się wewnątrz funkcji, w której jest zadeklarowana.

var a = 1;
var b = 2;

if (a === 1) {
  var a = 11; // the scope is global
  let b = 22; // the scope is inside the if-block

  console.log(a);  // 11
  console.log(b);  // 22
} 

console.log(a); // 11
console.log(b); // 2

Nie zapominaj również, że jest to funkcja ECMA6, więc nie jest jeszcze w pełni obsługiwana, więc lepiej zawsze przenosić ją do ECMA5 za pomocą Babel itp... aby uzyskać więcej informacji o wizycie babel strona internetowa

 55
Author: Alireza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-18 07:03:40

Oto przykład różnicy między tymi dwoma (wsparcie właśnie rozpoczęte dla chrome):
Tutaj wpisz opis obrazka

Jak widać zmienna var j nadal ma wartość poza zakresem pętli for( zakres blokowy), ale zmienna let i jest niezdefiniowana poza zakresem pętli for.

"use strict";
console.log("var:");
for (var j = 0; j < 2; j++) {
  console.log(j);
}

console.log(j);

console.log("let:");
for (let i = 0; i < 2; i++) {
  console.log(i);
}

console.log(i);
 55
Author: vlio20,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-05 12:03:19

Istnieją pewne subtelne różnice - let scoping zachowuje się bardziej jak zmienny scoping w mniej więcej każdym innym języku.

Np. przenika do bloku zamykającego, nie istnieją przed ich zadeklarowaniem itp.

Warto jednak zauważyć, że let jest tylko częścią nowszych implementacji Javascript i ma różny stopień wsparcia przeglądarki.

 54
Author: olliej,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-24 02:53:08

W najbardziej podstawowych terminach,

for (let i = 0; i < 5; i++) {
  // i accessible ✔️
}
// i not accessible 

for (var i = 0; i < 5; i++) {
  // i accessible ✔️
}
// i accessible ✔️

Sand piaskownica do zabawy ↓

Edit let vs var

 51
Author: Hasan Sefa Ozalp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-05-11 17:04:48
  • Zmienna Bez Podnoszenia

    let będą nie podnoszą do całego zakresu bloku, w którym się pojawiają. Natomiast var może podnieść jak poniżej.

    {
       console.log(cc); // undefined. Caused by hoisting
       var cc = 23;
    }
    
    {
       console.log(bb); // ReferenceError: bb is not defined
       let bb = 23;
    }
    

    Właściwie, na @Bergi, zarówno var, jak ilet są podnoszone .

  • Wywóz Śmieci

    Zakres blokowy {[5] } jest przydatny do zamykania i usuwania śmieci w celu odzyskania pamięci. Rozważmy,

    function process(data) {
        //...
    }
    
    var hugeData = { .. };
    
    process(hugeData);
    
    var btn = document.getElementById("mybutton");
    btn.addEventListener( "click", function click(evt){
        //....
    });
    

    Wywołanie zwrotne obsługi click w ogóle nie potrzebuje zmiennej hugeData. Teoretycznie po uruchomieniu process(..) Ogromna struktura danych {[11] } może być zbierana. Jest jednak możliwe, że niektóre silniki JS nadal będą musiały zachować tę ogromną strukturę, ponieważ funkcja click ma zamknięcie na całym zakresie.

    Jednak zakres bloków może sprawić, że ta ogromna struktura danych zostanie usunięta.

    function process(data) {
        //...
    }
    
    { // anything declared inside this block can be garbage collected
        let hugeData = { .. };
        process(hugeData);
    }
    
    var btn = document.getElementById("mybutton");
    btn.addEventListener( "click", function click(evt){
        //....
    });
    
  • let pętle

    let W pętli can ponownie wiąże ją do każdej iteracji pętli, upewniając się, że ponownie przypisano jej wartość z końca poprzedniej iteracji pętli. Rozważmy,

    // print '5' 5 times
    for (var i = 0; i < 5; ++i) {
        setTimeout(function () {
            console.log(i);
        }, 1000);  
    }
    

    Jednak zastąp var let

    // print 1, 2, 3, 4, 5. now
    for (let i = 0; i < 5; ++i) {
        setTimeout(function () {
            console.log(i);
        }, 1000);  
    }
    

    Ponieważ let tworzy nowe środowisko leksykalne z tymi nazwami dla a) wyrażenia inicjalizującego b) każdej iteracji (wcześniej do oceny wyrażenia przyrostowego), więcej szczegółów znajduje się tutaj.

 26
Author: zangw,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:53

Różnica jest w zakres zmiennych zadeklarowanych z każdym.

W praktyce istnieje wiele przydatnych konsekwencji różnicy w zakresie:]}
  1. let zmienne są widoczne tylko w ich najbliższym bloku ({ ... }).
  2. let zmienne są użyteczne tylko w liniach kodu, które występują po zmienna jest zadeklarowana (nawet jeśli są podnoszone!).
  3. let zmienne mogą nie być ponownie zgłoszony przez kolejne var lub let.
  4. Globalne let zmienne nie są dodawane do obiektu global window.
  5. let zmienne są łatwe w użyciu z zamknięciami (nie powodują warunków rasy).

Ograniczenia nałożone przez let zmniejszają widoczność zmiennych i zwiększają prawdopodobieństwo, że nieoczekiwane kolizje nazw zostaną znalezione wcześnie. Ułatwia to śledzenie i rozumowanie zmiennych, w tym ich osiągalność (pomoc w odzyskiwaniu nieużywanej pamięci).

W związku z tym, let zmienne są mniej narażone na problemy, gdy są używane w dużych programach lub gdy niezależnie opracowane frameworki są łączone w nowy i nieoczekiwany sposób.

var nadal może być przydatny, jeśli jesteś pewien, że chcesz uzyskać efekt pojedynczego wiązania przy użyciu zamknięcia w pętli (#5) lub do deklarowania zewnętrznych widocznych zmiennych globalnych w kodzie (#4). Wykorzystanie var do wywozu może zostać zastąpione jeśli export migruje z przestrzeni transpilerów do języka podstawowego.

Przykłady

1. Brak użycia poza najbliższym blokiem zamykającym: Ten blok kodu spowoduje błąd odniesienia, ponieważ drugie użycie x występuje poza blokiem, w którym jest zadeklarowane za pomocą let:

{
    let x = 1;
}
console.log(`x is ${x}`);  // ReferenceError during parsing: "x is not defined".

W przeciwieństwie do tego, ten sam przykład z var Działa.

2. No use before declaration:
Ten blok kodu rzuci ReferenceError przed kod może być uruchomiony, ponieważ x jest używany przed zadeklarowaniem:

{
    x = x + 1;  // ReferenceError during parsing: "x is not defined".
    let x;
    console.log(`x is ${x}`);  // Never runs.
}

Dla kontrastu, ten sam przykład z var parsuje i działa bez rzucania żadnych WYJĄTKÓW.

3. No redeclaration: Poniższy kod pokazuje, że zmienna zadeklarowana przez let nie może być później ponownie zgłoszona:

let x = 1;
let x = 2;  // SyntaxError: Identifier 'x' has already been declared

4. window:

var button = "I cause accidents because my name is too common.";
let link = "Though my name is common, I am harder to access from other JS files.";
console.log(link);  // OK
console.log(window.link);  // undefined (GOOD!)
console.log(window.button);  // OK

5. Łatwe użycie z zamknięciami: Zmienne deklarowane przez var nie działają dobrze z zamknięcia wewnątrz pętli. Oto prosta pętla, która wyprowadza sekwencję wartości, które zmienna i ma w różnych punktach czasu:

for (let i = 0; i < 5; i++) {
    console.log(`i is ${i}`), 125/*ms*/);
}

Konkretnie, to wychodzi:

i is 0
i is 1
i is 2
i is 3
i is 4

W JavaScript często używamy zmiennych znacznie później niż w momencie ich tworzenia. Kiedy pokazujemy to opóźniając wyjście z zamknięciem przekazanym do setTimeout:

for (let i = 0; i < 5; i++) {
    setTimeout(_ => console.log(`i is ${i}`), 125/*ms*/);
}

... wyjście pozostaje bez zmian, dopóki trzymamy się let. Natomiast gdybyśmy mieli używane var i zamiast:

for (var i = 0; i < 5; i++) {
    setTimeout(_ => console.log(`i is ${i}`), 125/*ms*/);
}

... pętla nieoczekiwanie wyświetla" i jest 5 " pięć razy:

i is 5
i is 5
i is 5
i is 5
i is 5
 21
Author: mormegil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-22 01:21:34

Oto przykład, aby dodać do tego, co inni już napisali. Załóżmy, że chcesz utworzyć tablicę funkcji adderFunctions, gdzie każda funkcja pobiera pojedynczy argument liczbowy i Zwraca sumę argumentu i indeks funkcji w tablicy. Próba wygenerowania adderFunctions za pomocą pętli za pomocą słowa kluczowego var nie będzie działać tak, jak ktoś może naiwnie oczekiwać:

// An array of adder functions.
var adderFunctions = [];

for (var i = 0; i < 1000; i++) {
  // We want the function at index i to add the index to its argument.
  adderFunctions[i] = function(x) {
    // What is i bound to here?
    return x + i;
  };
}

var add12 = adderFunctions[12];

// Uh oh. The function is bound to i in the outer scope, which is currently 1000.
console.log(add12(8) === 20); // => false
console.log(add12(8) === 1008); // => true
console.log(i); // => 1000

// It gets worse.
i = -8;
console.log(add12(8) === 0); // => true

Powyższy proces nie generuje żądanej tablicy funkcji, ponieważ zakres i wykracza poza iteracja bloku for, w którym każda funkcja została utworzona. Zamiast tego, na końcu pętli, i w zamknięciu każdej funkcji odnosi się do wartości i na końcu pętli (1000) dla każdej funkcji anonimowej w adderFunctions. To nie jest to, czego w ogóle chcieliśmy: mamy teraz tablicę 1000 różnych funkcji w pamięci o dokładnie takim samym zachowaniu. Jeśli następnie zaktualizujemy wartość i, mutacja wpłynie na wszystkie adderFunctions.

Jednak możemy spróbować ponownie używając let słowo kluczowe:

// Let's try this again.
// NOTE: We're using another ES6 keyword, const, for values that won't
// be reassigned. const and let have similar scoping behavior.
const adderFunctions = [];

for (let i = 0; i < 1000; i++) {
  // NOTE: We're using the newer arrow function syntax this time, but 
  // using the "function(x) { ..." syntax from the previous example 
  // here would not change the behavior shown.
  adderFunctions[i] = x => x + i;
}

const add12 = adderFunctions[12];

// Yay! The behavior is as expected. 
console.log(add12(8) === 20); // => true

// i's scope doesn't extend outside the for loop.
console.log(i); // => ReferenceError: i is not defined

Tym razem i jest odbiciem na każdej iteracji for pętli. Każda funkcja zachowuje teraz wartość i w momencie tworzenia funkcji i adderFunctions zachowuje się zgodnie z oczekiwaniami.

Teraz obrazek miesza oba zachowania i prawdopodobnie zobaczysz, dlaczego nie zaleca się mieszania nowszych let i const ze starszymi var w tym samym skrypcie. Może to skutkować jakimś spektakularnie mylącym kodem.

const doubleAdderFunctions = [];

for (var i = 0; i < 1000; i++) {
    const j = i;
    doubleAdderFunctions[i] = x => x + i + j;
}

const add18 = doubleAdderFunctions[9];
const add24 = doubleAdderFunctions[12];

// It's not fun debugging situations like this, especially when the
// code is more complex than in this example.
console.log(add18(24) === 42); // => false
console.log(add24(18) === 42); // => false
console.log(add18(24) === add24(18)); // => false
console.log(add18(24) === 2018); // => false
console.log(add24(18) === 2018); // => false
console.log(add18(24) === 1033); // => true
console.log(add24(18) === 1030); // => true
Nie pozwól, żeby ci się to przytrafiło. Użyj a linter.

Uwaga: jest to przykład dydaktyczny mający na celu zademonstrowanie var/let zachowanie w pętlach i z zamknięciami funkcji, które również byłyby łatwe do zrozumienia. To byłby okropny sposób na dodawanie liczb. Ale ogólna technika przechwytywania danych w anonimowych zamknięciach funkcji może być spotykana w świecie rzeczywistym w innych kontekstach. YMMV.

 21
Author: abroz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-09 22:24:59

Niech poniższe dwie funkcje pokażą różnicę:

function varTest() {
    var x = 31;
    if (true) {
        var x = 71;  // Same variable!
        console.log(x);  // 71
    }
    console.log(x);  // 71
}

function letTest() {
    let x = 31;
    if (true) {
        let x = 71;  // Different variable
        console.log(x);  // 71
    }
    console.log(x);  // 31
}
 18
Author: Abdennour TOUMI,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-26 16:18:38

let jest interesujący, ponieważ pozwala nam zrobić coś takiego:

(() => {
    var count = 0;

    for (let i = 0; i < 2; ++i) {
        for (let i = 0; i < 2; ++i) {
            for (let i = 0; i < 2; ++i) {
                console.log(count++);
            }
        }
    }
})();

Co skutkuje zliczeniem [0, 7].

]}

(() => {
    var count = 0;

    for (var i = 0; i < 2; ++i) {
        for (var i = 0; i < 2; ++i) {
            for (var i = 0; i < 2; ++i) {
                console.log(count++);
            }
        }
    }
})();

Liczy się tylko [0, 1].

 14
Author: Dmitry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-26 16:34:26

Funkcja VS zakres bloku:

Główną różnicą między var i let jest to, że zmienne zadeklarowane przez var zakresem funkcji . Podczas gdy funkcje zadeklarowane przez let to zakres blokowy . Na przykład:

function testVar () {
  if(true) {
    var foo = 'foo';
  }

  console.log(foo);
}

testVar();  
// logs 'foo'


function testLet () {
  if(true) {
    let bar = 'bar';
  }

  console.log(bar);
}

testLet(); 
// reference error
// bar is scoped to the block of the if statement 

Zmienne z var:

Kiedy pierwsza funkcja testVar zostanie wywołana zmienna foo, zadeklarowana przez var, jest nadal dostępna poza instrukcją if. Zmienna foo będzie dostępna wszędzie w zakresie testVar function .

Zmienne z let:

Kiedy druga funkcja testLet zostanie wywołana, zmienna bar, zadeklarowana przez let, jest dostępna tylko wewnątrz instrukcji if. Ponieważ zmienne zadeklarowane przez let to zakres bloku (gdzie blok jest kodem między nawiasami klamrowymi, np. if{} , for{}, function{}).

let zmienne nie są podnoszone:

Kolejna różnica pomiędzy var a let jest zmienną z zadeklarowaną z let nie daj się wciągnąć . Przykład jest najlepszym sposobem na zilustrowanie tego zachowania:

Zmienne z let nie daj się wciągnąć:]}

console.log(letVar);

let letVar = 10;
// referenceError, the variable doesn't get hoisted

Zmienne z var do get hoisted:

console.log(varVar);

var varVar = 10;
// logs undefined, the variable gets hoisted

Global let nie przywiązuje się do window:

Zmienna zadeklarowana przez let w globalnym zasięgu (który jest kodem, który nie jest w funkcji) nie zostanie dodana jako właściwość na global window object. Na przykład (ten kod jest w zasięgu globalnym):

var bar = 5;
let foo  = 10;

console.log(bar); // logs 5
console.log(foo); // logs 10

console.log(window.bar);  
// logs 5, variable added to window object

console.log(window.foo);
// logs undefined, variable not added to window object


Kiedy należy stosować let zamiast var?

Używaj let przez var Kiedy tylko możesz, ponieważ jest to po prostu bardziej szczegółowe. Zmniejsza to potencjalne konflikty nazewnictwa, które mogą wystąpić w przypadku dużej liczby zmiennych. var może być używany, gdy chcesz, aby globalna zmienna była jawnie na obiekcie window (zawsze uważnie rozważ, czy jest to naprawdę konieczne).

 14
Author: Willem van der Veen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-10 07:39:18

Wydaje się również, że przynajmniej w Visual Studio 2015, TypeScript 1.5, " var "pozwala na wiele deklaracji o tej samej nazwie zmiennej w bloku, a "let"nie.

To nie spowoduje błędu kompilacji:

var x = 1;
var x = 2;

To będzie:

let x = 1;
let x = 2;
 12
Author: RDoc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-28 09:31:05

var jest zmienną o zasięgu globalnym (hoist-able).

let i const to zakres blokowy.

Test.js

{
    let l = 'let';
    const c = 'const';
    var v = 'var';
    v2 = 'var 2';
}

console.log(v, this.v);
console.log(v2, this.v2);
console.log(l); // ReferenceError: l is not defined
console.log(c); // ReferenceError: c is not defined
 11
Author: Moslem Shahsavan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-28 12:42:16

Podczas Używania let

Słowo kluczowe let dołącza deklarację zmiennej do zakresu dowolnego bloku (Zwykle pary { .. }), w którym jest zawarta. Innymi słowy, let domyślnie przejmuje zakres dowolnego bloku dla jego deklaracji zmiennej.

let zmienne nie mogą być dostępne w obiekcie window, ponieważ nie mogą być dostępne globalnie.

function a(){
    { // this is the Max Scope for let variable
        let x = 12;
    }
    console.log(x);
}
a(); // Uncaught ReferenceError: x is not defined

Podczas Używania var

var A zmienne w ES5 mają zakresy w funkcjach czyli zmienne są ważne wewnątrz funkcji, a nie poza samą funkcją.

var zmienne mogą być dostępne w obiekcie window, ponieważ nie mogą być dostępne globalnie.

function a(){ // this is the Max Scope for var variable
    { 
        var x = 12;
    }
    console.log(x);
}
a(); // 12

Jeśli chcesz dowiedzieć się więcej Czytaj dalej poniżej

Jedno z najbardziej znanych pytań wywiadu na temat zakresu może również wystarczyć dokładne użycie let i var jak poniżej; {23]}

Podczas używania let

for (let i = 0; i < 10 ; i++) {
    setTimeout(
        function a() {
            console.log(i); //print 0 to 9, that is literally AWW!!!
        }, 
        100 * i);
}

Dzieje się tak dlatego, że przy użyciu let, dla każda iteracja pętli zmienna jest skalowana i posiada własną kopię.

Podczas używania var

for (var i = 0; i < 10 ; i++) {
    setTimeout(
        function a() {
            console.log(i); //print 10 times 10
        }, 
        100 * i);
}

Dzieje się tak dlatego, że podczas używania var, dla każdej iteracji pętli zmienna jest skalowana i ma współdzieloną kopię.

 9
Author: Ankur Soni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-22 13:22:19

Jeśli dobrze przeczytam specyfikację, to let na szczęście może być również wykorzystany w celu uniknięcia samo wywołujących się Funkcji używanych do symulacji tylko prywatnych członków- popularny wzorzec projektowy, który zmniejsza czytelność kodu, komplikuje debugowanie, który nie dodaje rzeczywistej ochrony kodu ani innych korzyści - może poza zaspokojeniem czyjegoś pragnienia semantyki, więc przestań go używać. / rant

var SomeConstructor;

{
    let privateScope = {};

    SomeConstructor = function SomeConstructor () {
        this.someProperty = "foo";
        privateScope.hiddenProperty = "bar";
    }

    SomeConstructor.prototype.showPublic = function () {
        console.log(this.someProperty); // foo
    }

    SomeConstructor.prototype.showPrivate = function () {
        console.log(privateScope.hiddenProperty); // bar
    }

}

var myInstance = new SomeConstructor();

myInstance.showPublic();
myInstance.showPrivate();

console.log(privateScope.hiddenProperty); // error

Patrz 'emulowanie prywatnych interfejsów '

 8
Author: Daniel Sokolowski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-12 05:29:57

ES6 wprowadził dwa nowe słowa kluczowe (let i const ) zastępujące var.

Kiedy potrzebujesz opóźnienia na poziomie bloku, możesz użyć let i const zamiast var.

Poniższa tabela podsumowuje różnicę między var, let i const

Tutaj wpisz opis obrazka

 8
Author: Srikrushna,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-26 11:39:21

Niektóre hacki z let:

1.

    let statistics = [16, 170, 10];
    let [age, height, grade] = statistics;

    console.log(height)

2.

    let x = 120,
    y = 12;
    [x, y] = [y, x];
    console.log(`x: ${x} y: ${y}`);

3.

    let node = {
                   type: "Identifier",
                   name: "foo"
               };

    let { type, name, value } = node;

    console.log(type);      // "Identifier"
    console.log(name);      // "foo"
    console.log(value);     // undefined

    let node = {
        type: "Identifier"
    };

    let { type: localType, name: localName = "bar" } = node;

    console.log(localType);     // "Identifier"
    console.log(localName);     // "bar"

Getter i setter z let:

let jar = {
    numberOfCookies: 10,
    get cookies() {
        return this.numberOfCookies;
    },
    set cookies(value) {
        this.numberOfCookies = value;
    }
};

console.log(jar.cookies)
jar.cookies = 7;

console.log(jar.cookies)
 7
Author: zloctb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-26 16:44:48

Poniżej pokazano, jak "let" i " var " różnią się w zakresie:

let gfoo = 123;
if (true) {
    let gfoo = 456;
}
console.log(gfoo); // 123

var hfoo = 123;
if (true) {
    var hfoo = 456;
}
console.log(hfoo); // 456

gfoo, zdefiniowany przez let początkowo znajduje się w zasięgu globalnym , A gdy zadeklarujemy gfoo ponownie wewnątrz if clause jego zakres zmieniony A gdy nowa wartość jest przypisana do zmiennej wewnątrz tego zakresu, nie wpływa na globalny zakres.

Podczas gdy hfoo, zdefiniowany przez var jest początkowo w zasięgu globalnym , ale ponownie, gdy zadeklarujemy go wewnątrz if clause, uznaje globalny zakres hfoo, chociaż var został ponownie użyty do jego zadeklarowania. A kiedy ponownie przypisujemy jej wartość, widzimy, że globalny zakres hfoo jest również dotknięty. To jest podstawowa różnica.

 6
Author: Piklu Dey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-07 11:25:15

Let jest częścią es6. Te funkcje wyjaśnią różnicę w łatwy sposób.

function varTest() {
  var x = 1;
  if (true) {
    var x = 2;  // same variable!
    console.log(x);  // 2
  }
  console.log(x);  // 2
}

function letTest() {
  let x = 1;
  if (true) {
    let x = 2;  // different variable
    console.log(x);  // 2
  }
  console.log(x);  // 1
}
 5
Author: Vipul Jain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-17 10:47:31

Let vs var. Chodzi o Zakres .

Zmienne Var są globalne i mogą być dostępne w zasadzie wszędzie, podczas gdy Niech zmienne nie są globalne i istnieją tylko do zamknięcia nawiasu zabija je.

Zobacz mój przykład poniżej i zauważ, jak zmienna lion (let) działa inaczej w dwóch konsolach.logi; staje się poza zasięgiem w 2. konsoli.log.

var cat = "cat";
let dog = "dog";

var animals = () => {
    var giraffe = "giraffe";
    let lion = "lion";

    console.log(cat);  //will print 'cat'.
    console.log(dog);  //will print 'dog', because dog was declared outside this function (like var cat).

    console.log(giraffe); //will print 'giraffe'.
    console.log(lion); //will print 'lion', as lion is within scope.
}

console.log(giraffe); //will print 'giraffe', as giraffe is a global variable (var).
console.log(lion); //will print UNDEFINED, as lion is a 'let' variable and is now out of scope.
 5
Author: daCoda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-18 00:49:32

Jak wspomniano powyżej:

Różnica polega na przeznaczeniu. var ma zasięg do najbliższej funkcji blok i let jest ograniczony do najbliższego bloku , który może być mniejszy niż blok funkcyjny. Oba są globalne, jeśli poza jakimkolwiek blok.Zobaczmy przykład:

Przykład1:

W obu moich przykładach mam funkcję myfunc. myfunc zawiera zmienną myvar równą 10. W moim pierwszym przykładzie sprawdzam czy myvar równa się 10 (myvar==10). Jeśli tak, deklaruję zmienną myvar (Teraz mam dwie zmienne myvar)używając słowa kluczowego var i przypisuję jej nową wartość (20). W następnym wierszu wypisuję jego wartość na mojej konsoli. Po bloku warunkowym ponownie wypisuję wartość myvar na mojej konsoli. Jeśli spojrzeć na wyjście z myfunc, myvar ma wartość równą 20.

let keyword

Przykład2: W drugim przykładzie zamiast używać słowa kluczowego var w moim bloku warunkowym deklaruję myvar używając słowa kluczowego let. Teraz kiedy wywołuję myfunc dostaję dwa różne wyjścia: myvar=20 i myvar=10.

Więc różnica jest bardzo prosta, tzn. jej zakres.

 4
Author: N Randhawa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-13 14:02:08

Teraz myślę, że jest lepsze przeskalowanie zmiennych do bloku instrukcji za pomocą let:

function printnums()
{
    // i is not accessible here
    for(let i = 0; i <10; i+=)
    {
       console.log(i);
    }
    // i is not accessible here

    // j is accessible here
    for(var j = 0; j <10; j++)
    {
       console.log(j);
    }
    // j is accessible here
}

Myślę, że ludzie zaczną używać let tutaj po tak, że będą mieli podobny zakres w JavaScript, jak inne języki, Java, C#, itp.

Osoby, które nie miały jasnego zrozumienia zakresu w JavaScript, wcześniej popełniały ten błąd.

Podnoszenie nie jest obsługiwane za pomocą let.

Przy takim podejściu błędy obecne w JavaScript są usuwane.

Zobacz ES6 in Depth: let and const żeby to lepiej zrozumieć.

 2
Author: swaraj patil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-26 16:33:53

Ten artykuł jasno określa różnicę między var, let i const

const jest sygnałem, że identyfikator nie zostanie ponownie przypisany.

let, jest sygnałem, że zmienna może być ponownie przypisana, np. licznik w pętli lub zamiana wartości w algorytmie. Sygnalizuje również że zmienna będzie używana tylko w bloku, w którym jest zdefiniowana, która nie zawsze jest całością funkcji zawierającej.

var jest teraz najsłabszym sygnałem dostępnym, gdy definiowanie zmiennej w JavaScript. Zmienna może być przypisana lub nie, a zmienna może lub nie może być używana dla całej funkcji, lub tylko dla przeznaczenie bloku lub pętli.

Https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75#.esmkpbg9b

 2
Author: anandharshan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-30 17:11:41

Chcę połączyć te słowa kluczowe z kontekstem wykonania, ponieważ kontekst wykonania jest w tym wszystkim ważny. Kontekst realizacji składa się z dwóch faz: fazy tworzenia i fazy realizacji. Ponadto każdy kontekst wykonania ma zmienne środowisko i środowisko zewnętrzne (jego środowisko leksykalne).

Podczas tworzenia kontekstu wykonawczego, var, let i const nadal będą przechowywać swoją zmienną w pamięci z niezdefiniowaną wartością w środowisku zmiennej podanej Kontekst Wykonania. Różnica jest w fazie realizacji. Jeśli użyjesz referencji do zmiennej zdefiniowanej za pomocą var przed przypisaniem jej wartości, będzie ona po prostu niezdefiniowana. Żaden wyjątek nie zostanie podniesiony.

Nie można jednak odwoływać się do zmiennej zadeklarowanej za pomocą let lub const, dopóki nie zostanie zadeklarowana. Jeśli spróbujesz go użyć, zanim zostanie zadeklarowany, wtedy podczas fazy wykonywania kontekstu wykonania pojawi się wyjątek. Teraz zmienna nadal będzie w pamięci, dzięki uprzejmości tworzenia Faza kontekstu wykonania, ale silnik nie pozwoli Ci na jego użycie:

function a(){
    b;
    let b;
}
a();
> Uncaught ReferenceError: b is not defined

Ze zmienną zdefiniowaną za pomocą var, jeśli silnik nie może znaleźć zmiennej w środowisku zmiennych bieżącego kontekstu wykonania, to przejdzie w górę łańcucha zakresu (środowisko zewnętrzne) i sprawdzi środowisko zmienne środowiska zewnętrznego dla zmiennej. Jeśli nie może go tam znaleźć, będzie kontynuował przeszukiwanie łańcucha zakresu. Tak nie jest w przypadku let i const.

Drugi cechą let jest to, że wprowadza zakres blokowy. Bloki są definiowane za pomocą nawiasów klamrowych. Przykłady obejmują bloki funkcyjne, bloki if, dla bloków, itp. Gdy deklarujesz zmienną za pomocą let inside of a block, zmienna jest dostępna tylko wewnątrz bloku. W rzeczywistości za każdym razem, gdy blok jest uruchamiany, np. w pętli for, tworzy nową zmienną w pamięci.

ES6 wprowadza również słowo kluczowe const do deklarowania zmiennych. const jest również zasięg blokowy. Różnica między let i const jest zmienne const muszą być zadeklarowane za pomocą inicjalizatora, w przeciwnym razie wygeneruje to błąd.

I wreszcie, jeśli chodzi o kontekst wykonania, zmienne zdefiniowane za pomocą var zostaną dołączone do obiektu 'this'. W globalnym kontekście wykonywania będzie to obiekt window w przeglądarkach. Tak nie jest w przypadku let lub const.

 2
Author: Donato,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-02-13 16:07:22

Myślę, że terminy i większość przykładów są nieco przytłaczające, Głównym problemem, który miałem osobiście z tą różnicą, jest zrozumienie, czym jest "blok". W pewnym momencie zdałem sobie sprawę, że blok będzie dowolnym nawiasem klamrowym z wyjątkiem IF statement. nawias otwierający { funkcji lub pętli zdefiniuje nowy blok, wszystko zdefiniowane przez let w nim, nie będzie dostępne po nawiasie zamykającym } tej samej rzeczy (funkcja lub pętla); Mając to na uwadze, łatwiej było zrozumieć:

let msg = "Hello World";

function doWork() { // msg will be available since it was defined above this opening bracket!
  let friends = 0;
  console.log(msg);

  // with VAR though:
  for (var iCount2 = 0; iCount2 < 5; iCount2++) {} // iCount2 will be available after this closing bracket!
  console.log(iCount2);
  
    for (let iCount1 = 0; iCount1 < 5; iCount1++) {} // iCount1 will not be available behind this closing bracket, it will return undefined
  console.log(iCount1);
  
} // friends will no be available after this closing bracket!
doWork();
console.log(friends);
 2
Author: Rafael Herscovici,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-28 02:21:13