ECMAScript 6 Wprowadzono Oświadczenie let .

Słyszałem, że jest opisany jako zmienna "lokalna", ale wciąż nie jestem pewien, jak zachowuje się inaczej niż słowo kluczowe var.

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

5477
TM. 18 kwiecień 2009, 00:09

26 odpowiedzi

Najlepsza odpowiedź

Zasady dotyczące zakresu skrótów

Główna różnica to reguły zakresu zakresu zakresu. Zmienne zadeklarowane przez var Słowo kluczowe są zaskoczone do bezpośredniego korpusu funkcji (stąd zakres funkcji), gdy zmienne letlet są przełączone do bezpośredniego bloku OCK oznaczony przez { } (Stąd zakres bloku).

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

  console.log(foo, bar);

  {
    let baz = "Bazz";
    console.log(baz);
  }

  console.log(baz); // ReferenceError
}

run();

Powodem, dla którego let został wprowadzony do języka, był to zakres funkcji jest mylący i był jednym z głównych źródeł błędów w JavaScript.

Spójrz na ten przykład od inne pytanie o stackoverflow:

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 Wydano do konsoli za każdym razem funcs[j](); został wywołany, ponieważ funkcje anonimowe były związane z taką samą zmienną.

Ludzie musieli tworzyć natychmiast wywołane funkcje, aby uchwycić poprawną wartość z pętli, ale był również owłosiony.

Podnoszenie

Podczas gdy zmienne zadeklarowane słowo kluczowe var są "podnoszone" na szczyt bloku, co oznacza, że są dostępne w ich otaczającym zakresie, nawet przed ich zadeklarowaniem:

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

run();

let zmienne nie są inicjowane, dopóki ich definicja zostanie oceniona. Dostęp do nich przed wyników inicjalizacji w ReferenceError. Zmienna powiedziała, że ma być w "czasowej strefie martwej" od początku bloku, aż inicjalizacja zostanie przetworzona.

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

checkHoisting();

Tworzenie globalnej nieruchomości obiektu

Na najwyższym poziomie let, w przeciwieństwie do var, nie tworzy nieruchomości na obiekcie globalnym:

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

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

Redeklaracja

W ścisłym trybie var pozwoli Ci ponownie zadeklarować tę samą zmienną w tym samym zakresie, gdy let podnosi 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
6545
33 revs, 23 users 29% 13 luty 2021, 04:48

let może być również używany do unikania problemów z zamknięciem. Wiąże się, a nie zachowanie starego odniesienia, jak pokazano w poniższych przykładach.

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 przycisku obsługi kliknij, a nie rzeczywistej wartości i.

Każdy program obsługi kliknięcia będzie odnosić się do tego samego obiektu, ponieważ jest tylko jeden obiekt licznika, który posiada 6, więc otrzymasz sześć na każdym kliknięciu.

Ogólne obejście jest owijanie tego w funkcji anonimowej i pass i jako argument. Takie problemy można również uniknąć, używając let zamiast var, jak pokazano w poniższym kodzie.

(Testowany w Chrome i Firefoksie 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>
674
Nash Bridges 29 październik 2019, 08:47

Myślę, że terminy i większość przykładów są nieco przytłaczające, Głównym problemem, jaki miałem osobiście różnicą, jest zrozumienie, co jest "blok". W pewnym momencie zrealizowałem, blok byłby dowolnym kręconym nawiasami z wyjątkiem oświadczenia IF. Uchwyt otwierający { funkcji lub pętli zdefiniuje nowy blok, wszystko zdefiniowane z let w nim, nie będzie dostępny po zamykającym wsporniku } tego samego (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
Dementic 28 kwiecień 2019, 02:21

Wcześniej były tylko dwie zakresy w JavaScript, I.e. Funkcjonalne i Globalne. Z "let" Słobienie JavaScript wprowadził teraz zmienne block-level.

Aby mieć pełne zrozumienie słowa kluczowego "pozwala", ES6: "Pozwól" słowa kluczowe do deklaracji zmiennej w JavaScript pomoże.

1
Peter Mortensen 26 listopad 2016, 16:27

enter image description here

Spójrz na ten obraz, stworzyłem jeden bardzo prosty przykład do demonstracji zmiennych const i let. Jak widać, gdy próbujesz zmienić zmienną const, otrzymasz błąd ( próbując zastąpić "nazwę", która jest stała "), ale spójrz na {{x3 }} Zmienna ...

Najpierw oświadczymy let age = 33, a później przypisz inną wartość age = 34;, co jest w porządku, nie mamy żadnych błędów, gdy próbujemy zmienić zmienną let

1
Mile Mijatović 16 luty 2019, 17:26

Oto Wyjaśnienie słowa kluczowego {x0}} z kilkoma przykładami.

let działa bardzo podobnie jak var. Główną różnicą jest to, że zakres zmiennej var jest całą funkcją obejmującą

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

Należy pamiętać, że tylko przeglądarki Mozilli i Chrome. Tj. Safari i potencjalnie nie.

153
Jack Bashford 24 czerwiec 2019, 02:52

Zaakceptowana odpowiedź brakuje punktu:

{
  let a = 123;
};

console.log(a); // ReferenceError: a is not defined
123
William 14 lipiec 2016, 14:13

let

Zakres blokowy

Zmienne zadeklarowane przy użyciu słowa kluczowego let są blokowe, co oznacza, że są dostępne tylko w Block, w którym zostały zadeklarowane.

Na najwyższym poziomie (poza funkcją)

Na najwyższym poziomie zmienne zadeklarowane przy użyciu let nie tworzą właściwości na 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 bloku), 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 przy użyciu let wewnątrz bloku nie można uzyskać dostępu na zewnątrz tego bloku.

{
  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 z let w pętlach można odnosić 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żywasz let zamiast var w pętli, przy każdej iteracji otrzymasz nową zmienną. Oznacza to, że można bezpiecznie użyć zamknięcia wewnątrz pętli.

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

Ze względu na Temporal Martre Zone, Zmienne zadeklarowane przy użyciu let nie mogą być dostępne przed ich zadeklarowaniem. Próba tego rzuca błąd.

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

Brak ponownego deklarstwa

Nie możesz zadeklarować tej samej zmiennej wielokrotnie przy użyciu let. Nie możesz również zadeklarować zmiennej przy użyciu let z tym samym identyfikatorem, co inna zmienna, która została zadeklarowana przy użyciu 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 dość podobny do let - jest blokowy i ma TDZ. Istnieją jednak dwie rzeczy, które są różne.

Brak ponownego przypisywania

Zmienna zadeklarowana przy użyciu const nie może zostać 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ć niezmienny obiekt, powinieneś użyć Object.freeze().

Inicjator jest wymagany

Zawsze musisz określić wartość przy deklaracji zmiennej za pomocą const.

const a; // SyntaxError: Missing initializer in const declaration
98
ketchupisred 25 październik 2018, 20:54

Oto przykład dla różnicy między nimi (obsługa właśnie uruchomiona dla Chrome):
Wpisz opis obrazu tutaj

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

"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
vlio20 5 czerwiec 2019, 12:03

Istnieją pewne subtelne różnice - let SCOPING zachowuje się bardziej jak zmienne scoping robi w mniej więcej innych językach.

Na przykład Zakręca do bloku otaczającego, nie istnieją, zanim zostaną ogłoszone itp.

Jednak warto zauważyć, że let jest tylko częścią nowszych implementacji JavaScript i ma różne stopnie Obsługa przeglądarki.

54
Jack Bashford 24 czerwiec 2019, 02:53

Oto przykład dodawania do tego, co inni już napisali. Załóżmy, że chcesz wykonać tablicę funkcji, adderFunctions, gdzie każda funkcja zajmuje pojedynczy argument numeryczny i zwraca sumę argumentu i indeks funkcji w tablicy. Próbując wygenerować adderFunctions za pomocą pętli za pomocą słowa kluczowego {x2}} nie będzie działać tak, jak ktoś może się spodziewać:

// 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 SOUND przedłuża się poza iterment blokiem {X1}}, w którym tworzono każdą funkcję. Zamiast tego, na końcu pętli, i w każdej zamknięciu funkcji odnosi się do wartości i na końcu pętli (1000) dla każdej anonimowej funkcji w adderFunctions. To nie jest to, czego chcieliśmy: teraz mamy tablicę 1000 różnych funkcji w pamięci z dokładnie tym samym zachowaniem. A jeśli następnie aktualizujemy wartość i, mutacja wpłynie na wszystkie adderFunctions.

Jednak możemy spróbować ponownie za pomocą słowa kluczowego let:

// 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 odbijany na każdej iteracji pętli for. Każda funkcja utrzymuje teraz wartość i w momencie tworzenia funkcji, a adderFunctions zachowuje się zgodnie z oczekiwaniami.

Teraz obraz wymieszanie dwóch zachowań i prawdopodobnie zobaczysz, dlaczego nie zaleca się mieszania nowszego let i const ze starszym var w tym samym skrypcie. Może to spowodować, że niektóre spektakularnie mylący kod.

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 to się stało. Użyj linszej.

Uwaga: Jest to przykład nauczania przeznaczony do wykazania zachowania {X1}} / let Byłby to straszny sposób, aby dodać liczby. Ale ogólna technika przechwytywania danych w anonimowych zamknięciach funkcji może być napotkana w rzeczywistym świecie w innych kontekstach. Ymmv.

21
abroz 9 październik 2017, 22:24

Niech następujące dwie funkcje pokazują 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
Peter Mortensen 26 listopad 2016, 16:18

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 powoduje liczenie [0, 7].

Natomiast

(() => {
    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
Peter Mortensen 26 listopad 2016, 16:34

Funkcja VS Block Zakres:

Główną różnicą między var i let jest to, że zmienne zadeklarowane z var funkcja scoped . Mając na uwadze, że funkcje zadeklarowane za pomocą let blokowane blokowane . 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:

Gdy pierwsza funkcja testVar zostanie zwana zmienną foo, zadeklarowaną z var, jest nadal dostępny poza oświadczeniem if. Ta zmienna foo byłaby dostępna wszędzie w ramach funkcji testVar .

zmienne z let:

Gdy druga funkcja testLet zostanie zwana paskiem zmiennym, zadeklarowany z let, jest dostępny tylko w oświadczeniu if. Ponieważ zmienne zadeklarowane z let blokowanie blokowania (gdzie blok jest kodem między nawiasami kręconymi e.g {x4}}, for{}, function{}).

Zmienne let nie podnosi się:

Kolejna różnica między var a let jest zmienne z zadeklarowanymi z let Nie otrzymuj podnośnika . Przykład jest najlepszym sposobem na zilustrowanie tego zachowania:

Zmienne z let nie Get Hoisted:

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 jest dołączony do window:

Zmienna zadeklarowana z let w globalnym zakresie (który jest kodem, który nie jest w funkcji) nie jest dodawany jako obiekt w obiekcie Global {X1}}. Na przykład (ten kod jest w zakresie 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 użyć let nad var?

Użyj let nad var, gdy tylko możesz, ponieważ jest po prostu bardziej specyficzny. Zmniejsza to potencjalne konflikty nazewnictwa, które mogą wystąpić w przypadku radzenia sobie z dużą liczbą zmiennych. var może być używany, gdy chcesz wyraźnie znaleźć zmienną globalną na obiekcie window (zawsze uważaj starannie, jeśli jest to naprawdę konieczne).

14
Suraj Rao 10 wrzesień 2018, 07:39

Wydaje się również, że przynajmniej w Visual Studio 2015, maszynopis: 1.5, "VAR" umożliwia wiele deklaracji tej samej nazwy zmiennej w bloku, a "niech" nie.

Nie wygeneruje błędu kompilacji:

var x = 1;
var x = 2;

To będzie:

let x = 1;
let x = 2;
12
John Slegers 28 listopad 2016, 09:31

var jest zmienną globalnym zakresem (wyciągnięciem).

let i const to zakres bloku.

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
Moslem Shahsavan 28 październik 2017, 12:42

przy użyciu let

Słowo kluczowe let przywiązuje zmienną deklarację do zakresu dowolnego bloku (powszechnie { .. } para) jest zawarte w innych słowach

Zmienne let nie mogą być dostępne w obiekcie window, ponieważ nie mogą być dostępne na całym świecie.

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

przy użyciu var

var i zmienne w ES5 ma zakresy w funkcjach, co oznacza, że zmienne są ważne w zależności od funkcji, a nie na zewnątrz samej funkcji.

Zmienne var można uzyskać do obiektu window, ponieważ nie mogą być dostępne na całym świecie.

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

Jeśli chcesz wiedzieć więcej, czytaj poniżej

Jednym z najsłynniejszych kwestii wywiadów w zakresie może wystarczyć dokładne użycie let i var jak poniżej;

przy użyciu 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, ponieważ przy użyciu let, dla każdej iteracji pętli zmienna jest skromna i ma własną kopię.

przy użyciu var

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

Dzieje się tak, ponieważ przy użyciu var, dla każdej iteracji pętli zmienna jest zasłoniona i ma wspólną kopię.

9
Ankur Soni 22 maj 2018, 13:22

Jeśli przeczytałem specyfikacje, a następnie let na szczęście może być również wykorzystany, aby uniknąć Same wywołanie funkcji używany do symulacji tylko prywatnych członków - popularny wzór projektu, który zmniejsza czytelność kodu, komplikuje debugowanie, co dodaje Prawdziwa ochrona kodu lub inna korzyść - z wyjątkiem może spełnienia 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 "emulujące prywatne interfejsy

8
Daniel Sokolowski 12 styczeń 2019, 05:29

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 seter 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
Peter Mortensen 26 listopad 2016, 16:44

Poniższy pokazuje, jak "pozwala" i "var" są różne 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 jest w globalnym zakresie , a kiedy deklarujemy gfoo ponownie wewnątrz if clause jego < EM> Zakres się zmieniono , a gdy nowa wartość jest przypisana do zmiennej w tym zakresie, który jest nie wpływa na zasięg globalny .

Mając na uwadze, że hfoo, zdefiniowany przez var jest początkowo w globalnym zakresie , ale ponownie, gdy zadeklarujemy go w if clause, uważa, że globalny zakres HFOO, chociaż Var został ponownie użyty, aby go zadeklarować. A kiedy ponownie przypisujemy jego wartość, widzimy, że dotknie się również globalny zakres HFOO. To jest różnica główna.

6
Piklu Dey 7 wrzesień 2019, 11:25

Niech jest częścią ES6. Funkcje te 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
Vipul Jain 17 grudzień 2017, 10:47

Niech vs var. Chodzi o zakres .

zmienne VAR są globalne i mogą być dostępne w zasadzie wszędzie, podczas gdy pozwalają zmienne nie są globalne i istnieją tylko aż do zamykania nawiasów zabija ich.

Zobacz mój przykład poniżej i zwróć uwagę, jak zmienna Lwa (LEP) działa inaczej w dwóch konsoli.logach; Staje się poza zakresem w drugiej 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
daCoda 18 kwiecień 2019, 00:49

Ten artykuł wyraźnie określa różnicę między Var, Let and Const

const jest sygnałem, który identyfikator nie zostanie ponownie przypisany.

let, jest sygnałem, który zmienna może być przypisana, np licznik w pętli lub wymianę wartości w algorytmie. To także sygnały że zmienna zostanie użyta tylko w bloku, który jest zdefiniowany, który nie zawsze jest cała funkcja zawierająca.

var jest teraz najsłabszym sygnałem dostępnym, gdy zdefiniujesz zmienną w javascript. Zmienna może lub nie może być przypisana, a zmienna może lub nie może być używana do całej funkcji, czy tylko dla cel bloku lub pętli.

https://medium.com/javascript-sene/javascript-es6-var-let-Const-ba58b8dcde75#.esmkpbg9b.

2
FelixSFD 30 kwiecień 2017, 17:11

Chcę połączyć te słowa kluczowe do kontekstu wykonania, ponieważ kontekst wykonania jest ważny w tym wszystkim. Kontekst wykonania ma dwa fazy: fazę tworzenia i faza wykonania. Ponadto każdy kontekst wykonania ma zmienne środowisko i środowisko zewnętrzne (jego środowisko leksykalne).

Podczas fazy tworzenia kontekstu wykonawczego, Let i Const nadal będą przechowywać swoją zmienną w pamięci o niezdefiniowanej wartości w środowisku zmiennym danego kontekstu wykonania. Różnica polega na fazie wykonania. Jeśli używasz odniesienia A zmienna zdefiniowana z VaR, zanim zostanie przypisana wartość, po prostu będzie niezdefiniowany. Nie zostanie podniesiony wyjątku.

Nie można jednak odwoływać się do zmiennej zadeklarowanej z Let lub Const, dopóki nie zostanie zadeklarowany. Jeśli próbujesz go użyć, zanim zostanie zadeklarowany, wyjątek zostanie podniesiony podczas fazy wykonania kontekstu wykonawczego. Teraz zmienna będzie nadal w pamięci, dzięki uprzejmości fazy utworzenia kontekstu wykonawczego, ale silnik nie pozwoli Ci go używać:

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

Z zmienną zdefiniowaną z VaR, jeśli silnik nie może znaleźć zmiennej w aktualnym środowisku wykonania kontekstu, wówczas podchodzi do łańcucha zasięgu (zewnętrznego środowiska) i sprawdzić zmienne środowisko środowiska zewnętrznego dla zmiennej. Jeśli nie może go znaleźć, nadal będzie wyszukiwał łańcuch zakresu. Tak nie jest w przypadku Let and Const.

Drugą cechą LUB jest wprowadza zakres bloków. Bloki są definiowane przez kręcone klamry. Przykłady obejmują bloki funkcyjne, jeśli bloki, dla bloków itp. Podczas deklarowania zmiennej z pozwalającym wewnątrz bloku zmienna jest dostępna tylko wewnątrz bloku. W rzeczywistości za każdym razem, gdy blok jest uruchomiony, taki jak w pętli, utworzy nową zmienną w pamięci.

ES6 wprowadza również słowo kluczowe CNA do deklaracji zmiennych. Const jest również blokowany blokowany. Różnica między Let a Const polega na tym, że zmienne CING muszą być zadeklarowane za pomocą inicjatora, albo wygeneruje błąd.

I wreszcie, jeśli chodzi o kontekst wykonania, zmienne zdefiniowane z VAR zostaną podłączone do obiektu "Ten". W kontekście wykonania globalnego, który będzie obiektem okna w przeglądarkach. Nie jest to przypadek na pozwolenie lub const.

2
Donato 13 luty 2019, 16:07

ES6 wprowadzono dwa nowe słowo kluczowe ( pozwala i const ) na przełączanie var .

Gdy potrzebujesz spowolnienia poziomu bloku, możesz iść z Let i Const zamiast VaR.

Poniższa tabela podsumowuje różnicę między Var, Let and Const

enter image description here

8
Srikrushna 26 styczeń 2020, 11:39

Teraz myślę, że jest lepsze skopowanie zmiennych do bloku wyciągów 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ą korzystać z Dudek po tak, że będą miały podobną scoping w JavaScript, jak inne języki, Java, C # itp.

Ludzie, a nie jasne zrozumienie dotyczące zakresu skrótu w JavaScript, który wcześniej popełnił błąd.

Podnośnik nie jest obsługiwany za pomocą let.

Z tym podejściem błędami obecnym w JavaScript zostaną usunięte.

Patrz ES6 Głębokość: Pozwól i Const lepiej zrozumieć.

2
Peter Mortensen 26 listopad 2016, 16:33