ECMAScript 6 wprowadził to let
oświadczenie .
Słyszałem, że jest opisywana jako zmienna „lokalna”, ale wciąż nie jestem pewien, jak zachowuje się inaczej niż var
słowo kluczowe.
Jakie są różnice? Kiedy należy let
zużyć var
?
ECMAScript 6 wprowadził to let
oświadczenie .
Słyszałem, że jest opisywana jako zmienna „lokalna”, ale wciąż nie jestem pewien, jak zachowuje się inaczej niż var
słowo kluczowe.
Jakie są różnice? Kiedy należy let
zużyć var
?
let
jest zawarty w wersji 6 edycji i najprawdopodobniej będzie w ostatecznej specyfikacji.Odpowiedzi:
Zasady określania zakresu
Główną różnicą są zasady określania zakresu. Zmienne zadeklarowane przez
var
słowo kluczowe mają zasięg do bezpośredniego ciała funkcji (stąd zakres funkcji), alet
zmienne są do bezpośredniego otaczającego bloku oznaczonego przez{ }
(stąd zakres bloku).Powodem
let
wprowadzenia słowa kluczowego do języka był zakres funkcji, który jest mylący i był jednym z głównych źródeł błędów w JavaScript.Spójrz na ten przykład z innego pytania dotyczącego przepełnienia stosu :
My value: 3
był wysyłany do konsoli za każdym razem, gdyfuncs[j]();
wywoływano, ponieważ anonimowe funkcje były powiązane z tą samą zmienną.Ludzie musieli tworzyć natychmiast wywoływane funkcje, aby uchwycić prawidłową wartość z pętli, ale było to również owłosione.
Podnoszenie
Podczas gdy zmienne zadeklarowane za pomocą
var
słowa kluczowego są podnoszone (inicjowaneundefined
przed uruchomieniem kodu), co oznacza, że są dostępne w swoim zakresie obejmującym nawet przed zadeklarowaniem:let
zmienne nie są inicjowane, dopóki ich definicja nie zostanie oceniona. Dostępu do nich przed otrzymaniem wyników inicjujących w AReferenceError
. Zmienna mówi się, że znajduje się w „czasowej martwej strefie” od początku bloku do momentu przetworzenia inicjalizacji.Tworzenie globalnej właściwości obiektu
Na najwyższym poziomie,
let
w przeciwieństwie dovar
, nie tworzy właściwości na obiekcie globalnym:Deklaracja
W trybie ścisłym
var
pozwoli Ci ponownie zadeklarować tę samą zmienną w tym samym zakresie, jednocześnielet
podnosząc błąd SyntaxError.źródło
let
wyrażenie blokowelet (variable declaration) statement
jest niestandardowe i zostanie w przyszłości usunięte, bugzilla.mozilla.org/show_bug.cgi?id=1023609 .let
można również użyć, aby uniknąć problemów z zamknięciami. Wiąże świeżą wartość zamiast utrzymywać stare odniesienie, jak pokazano w poniższych przykładach.Powyższy kod pokazuje klasyczny problem z zamykaniem JavaScript. Odwołanie do
i
zmiennej jest przechowywane w zamknięciu modułu obsługi kliknięć zamiast rzeczywistej wartościi
.Każda procedura obsługi pojedynczego kliknięcia będzie odnosić się do tego samego obiektu, ponieważ jest tylko jeden obiekt licznika, który ma 6, więc dostajesz sześć za każdym kliknięciem.
Ogólnym obejściem jest zawinięcie tego w anonimową funkcję i przekazanie jej
i
jako argumentu. Takich problemów można teraz również uniknąć, używająclet
zamiast tego,var
jak pokazano w poniższym kodzie.(Testowane w Chrome i Firefox 50)
źródło
let
, ale ostrzega „6” dla wszystkich przycisków. Czy masz jakieś źródło, które mówi, jaklet
ma się zachowywać?let
byłby tak przydatny. Ustawienie detektorów zdarzeń w pętli nie wymaga już bezpośrednio wywoływanego wyrażenia funkcji do lokalnego określania zakresui
przy każdej iteracji.Jaka jest różnica między
let
ivar
?var
instrukcji jest znana w całej funkcji, w której jest zdefiniowana, od początku funkcji. (*)let
instrukcji jest znana tylko w bloku, w którym jest zdefiniowana, od momentu jej zdefiniowania. (**)Aby zrozumieć różnicę, rozważ następujący kod:
Tutaj możemy zobaczyć, że nasza zmienna
j
jest znana tylko w pierwszej pętli for, ale nie przed i po. Jednak nasza zmiennai
jest znana w całej funkcji.Należy również wziąć pod uwagę, że zmienne o zasięgu blokowym nie są znane przed zadeklarowaniem, ponieważ nie są podnoszone. Nie można również ponownie ustawić tej samej zmiennej o zasięgu blokowym 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ą żadnych błędów w przypadku wielu deklaracji.
Czy korzystanie z niego jest
let
dziś bezpieczne ?Niektórzy twierdzą, że w przyszłości będziemy używać TYLKO instrukcji let, a instrukcje var staną się nieaktualne. Kyle Simpson, guru JavaScript, napisał bardzo skomplikowany artykuł o tym, dlaczego uważa, że tak nie będzie .
Jednak dzisiaj zdecydowanie tak nie jest. W rzeczywistości musimy zadać sobie pytanie, czy korzystanie z tego
let
oświadczenia jest bezpieczne . Odpowiedź na to pytanie zależy od środowiska:Jeśli piszesz kod JavaScript po stronie serwera ( Node.js ), możesz bezpiecznie użyć
let
instrukcji.Jeśli piszesz kod JavaScript po stronie klienta i używasz transpilatora opartego na przeglądarce (takiego jak Traceur lub Babel-standalone ), możesz bezpiecznie użyć tego
let
oświadczenia, 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 transpilatora opartego na Węźle (takiego jak skrypt powłoki traceur lub Babel ), możesz bezpiecznie użyć
let
instrukcji. Ponieważ Twoja przeglądarka będzie wiedziała tylko o transpilowanym kodzie, wady wydajności powinny być ograniczone.Jeśli piszesz kod JavaScript po stronie klienta i nie używasz transpilatora, musisz rozważyć obsługę przeglądarki.
Nadal istnieją niektóre przeglądarki, które w ogóle nie obsługują
let
:Jak śledzić obsługę przeglądarki
Aby
let
zapoznać się z aktualnym przeglądem przeglądarek obsługujących to oświadczenie podczas czytania tej odpowiedzi, zobacz tęCan I Use
stronę .(*) Zmienne o zasięgu globalnym i funkcjonalnym mogą być inicjowane i używane przed zadeklarowaniem, ponieważ zmienne JavaScript są podnoszone . Oznacza to, że deklaracje są zawsze na szczycie zakresu.
(**) Zmienne o zasięgu blokowym nie są podnoszone
źródło
i
JEST znany wszędzie w bloku funkcyjnym! Zaczyna się jakoundefined
(z powodu podnoszenia) do momentu przypisania wartości! ps:let
jest również podnoszony (na górę, w której znajduje się blok), ale da znak,ReferenceError
gdy będzie się do niego odwoływał w bloku przed pierwszym przypisaniem. (ps2: Jestem facetem trochę za średnikiem, ale tak naprawdę nie potrzebujesz średnika po bloku). To powiedziawszy, dziękuję za dodanie kontroli rzeczywistości dotyczącej wsparcia!let
ivar
!let
iconst
zostały zalecane do użytku, kiedy rzeczywiście potrzebują dodatkowej funkcjonalności , gdyż egzekwowanie / sprawdzanie tych dodatkowych funkcji (jak tylko do zapisu const) wynik w „więcej pracy „(i dodatkowe węzły zakresu w drzewie zakresu) dla (aktualnych) silników w celu wymuszenia / sprawdzenia / weryfikacji / konfiguracji.Oto wyjaśnienie
let
słowa kluczowego z kilkoma przykładami.Ta tabela na Wikipedii pokazuje, które przeglądarki obsługują Javascript 1.7.
Pamiętaj, że obsługują go tylko przeglądarki Mozilla i Chrome. IE, Safari i potencjalnie inni nie.
źródło
let
msdn.microsoft.com/en-us/library/ie/dn342892%28v=vs.85%29.aspxW zaakceptowanej odpowiedzi brakuje punktu:
źródło
for
inicjalizatorze pętli, co radykalnie zawęziło zakres zastosowania ograniczeńlet
. Pozytywne.let
Zablokuj zakres
Zmienne zadeklarowane przy użyciu
let
słowa kluczowego mają zasięg blokowy, 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 obiektu globalnego.Wewnątrz funkcji
Wewnątrz funkcji (ale poza blokiem)
let
ma taki sam zasięg jakvar
.Wewnątrz bloku
Do zmiennych zadeklarowanych za pomocą
let
wewnątrz bloku nie można uzyskać dostępu poza tym blokiem.Wewnątrz pętli
Do zmiennych zadeklarowanych
let
w pętlach można odwoływać się tylko wewnątrz tej pętli.Pętle z zapięciami
Jeśli użyjesz
let
zamiastvar
w pętli, z każdą iteracją otrzymujesz nową zmienną. Oznacza to, że możesz bezpiecznie użyć zamknięcia wewnątrz pętli.Czasowa martwa strefa
Ze względu na czasową martwą strefę , zmienne zadeklarowane za pomocą
let
nie mogą być dostępne przed zadeklarowaniem. Próba zrobienia tego powoduje błąd.Brak ponownego zgłoszenia
Nie można zadeklarować tej samej zmiennej wiele razy przy użyciu
let
. Nie można również zadeklarować zmiennej zalet
pomocą tego samego identyfikatora, co inną zmienną, która została zadeklarowana za pomocąvar
.const
const
jest dość podobny dolet
- ma blokowy zasięg i ma TDZ. Istnieją jednak dwie rzeczy, które są różne.Bez ponownego przypisywania
Zmiennej zadeklarowanej za pomocą
const
nie można ponownie przypisać.Zauważ, że nie oznacza to, że wartość jest niezmienna. Jego właściwości wciąż można zmienić.
Jeśli chcesz mieć niezmienny obiekt, powinieneś użyć
Object.freeze()
.Wymagany jest inicjator
Zawsze musisz podać wartość, deklarując zmienną za pomocą
const
.źródło
Oto przykład różnicy między nimi (obsługa właśnie uruchomiona dla chrome):
Jak widać,
var j
zmienna nadal ma wartość poza zakresem pętli for (zakres bloku), alelet i
zmienna jest niezdefiniowana poza zakresem pętli for.źródło
Istnieją pewne subtelne różnice -
let
zakresy zachowują się bardziej jak zmienne zakresy w mniej więcej dowolnym innym języku.np. obejmuje zakres otaczającego bloku, nie istnieją zanim zostaną zadeklarowane itp.
Warto jednak zauważyć, że
let
jest to tylko część nowszych implementacji Javascript i ma różne stopnie obsługi przeglądarki .źródło
let
jest uwzględniony w wersji roboczej 6. edycji i najprawdopodobniej będzie w ostatecznej specyfikacji.let
. Safari, IE i Chome nie wszystkie.let
nie podnosi, aby użyć zmiennej zdefiniowanej przezlet
definicję na górze bloku. Jeśli maszif
instrukcję, która jest więcej niż tylko kilkoma wierszami kodu, możesz zapomnieć, że nie możesz użyć tej zmiennej, dopóki nie zostanie zdefiniowana. WIELKI PUNKT !!!let
będzie podnosić zmiennej do górnej części bloku Jednak odwołanie do zmiennej w bloku przed otrzymaniem wyników deklaracji zmiennej w. ReferenceError (moja uwaga: zamiast stary dobryundefined
). Na zmienna znajduje się w „czasowej martwej strefie” od początku bloku do momentu przetworzenia deklaracji. ” To samo dotyczy „instrukcji przełączania, ponieważ istnieje tylko jeden podstawowy blok”. Źródło: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…Główną różnicą jest zakres różnicy, natomiast let mogą być dostępne tylko wewnątrz zakresu to zadeklarowanej, jak w pętli for var mogą być dostępne poza pętlą na przykład. Z dokumentacji w MDN (przykłady również z MDN):
Nie zapominaj także, że jest to funkcja ECMA6, więc nie jest jeszcze w pełni obsługiwana, więc lepiej zawsze przenosi ją na ECMA5 przy użyciu Babel itp. ... aby uzyskać więcej informacji na temat odwiedzenia strony Babel
źródło
Zmienna bez podnoszenialet
nie będzie podnosić do całego zakresu bloku, w którym się pojawiają. Przeciwnie,var
może podnosić jak poniżej.Właściwie, Per @Bergi, Both
var
ilet
są podnoszone .Zbieranie śmieci
Zakres bloków
let
jest przydatny w odniesieniu do zamknięć i odśmiecania pamięci w celu odzyskania pamięci. Rozważać,Funkcja
click
zwrotna programu obsługi w ogóle nie potrzebujehugeData
zmiennej. Teoretycznie poprocess(..)
uruchomieniu ogromna struktura danychhugeData
mogłaby zostać wyrzucona do śmieci. Jednak możliwe jest, że niektóre silniki JS nadal będą musiały zachować tę ogromną strukturę, ponieważclick
funkcja ma zamknięcie w całym zakresie.Jednak zakres bloku może sprawić, że ta ogromna struktura danych zostanie wyrzucona do śmieci.
let
pętlelet
w pętli może ponownie powiązać ją z każdą iteracją pętli, pamiętając o ponownym przypisaniu jej wartości z końca poprzedniej iteracji pętli. Rozważać,Jednakże, należy wymienić
var
zlet
Ponieważ
let
stwórz nowe środowisko leksykalne o tych nazwach dla a) wyrażenia inicjującego b) każdej iteracji (poprzednio do oceny wyrażenia przyrostowego), więcej szczegółów znajduje się tutaj .źródło
Oto przykład dodania do tego, co już napisali inni. Załóżmy, że chcesz utworzyć tablicę funkcji,
adderFunctions
w której każda funkcja pobiera pojedynczy argument Number i zwraca sumę argumentu oraz indeks funkcji w tablicy. Próba wygenerowaniaadderFunctions
za pomocą pętli przy użyciuvar
słowa kluczowego nie będzie działać tak, jak ktoś mógłby naiwnie oczekiwać:Powyższy proces nie generuje pożądanej tablicy funkcji, ponieważ
i
zakres wykracza poza iteracjęfor
bloku, w którym każda funkcja została utworzona. Zamiast tego na końcu pętli zamknięciei
w każdej funkcji odnosi się doi
wartości na końcu pętli (1000) dla każdej anonimowej funkcji wadderFunctions
. Nie tego w ogóle chcieliśmy: mamy teraz w pamięci tablicę 1000 różnych funkcji o dokładnie takim samym zachowaniu. A jeśli następnie zaktualizujemy wartośći
, mutacja wpłynie na wszystkieadderFunctions
.Możemy jednak spróbować ponownie, używając
let
słowa kluczowego:Tym razem
i
odbija się przy każdej iteracjifor
pętli. Każda funkcja zachowuje teraz wartośći
w momencie jej tworzenia, orazadderFunctions
zachowuje się zgodnie z oczekiwaniami.Teraz, obraz mieszający te dwa zachowania i prawdopodobnie zobaczysz, dlaczego nie zaleca się mieszania nowszych
let
iconst
starszychvar
w tym samym skrypcie. Może to spowodować spektakularnie zagmatwany kod.Nie pozwól, aby ci się to przytrafiło. Użyj wkładki.
źródło
let value = i;
.for
Instrukcja tworzy leksykalny blok.Różnica polega na zakresie zmiennych zadeklarowanych z każdą z nich.
W praktyce istnieje szereg przydatnych konsekwencji różnicy w zakresie:
let
zmienne są widoczne tylko w ich najbliższym otaczającym bloku ({ ... }
).let
zmienne są użyteczne tylko w wierszach kodu, które występują po zadeklarowaniu zmiennej (nawet jeśli są podnoszone !).let
zmienne nie mogą być ponownie zadeklarowane przez kolejnevar
lublet
.let
Zmienne globalne nie są dodawane dowindow
obiektu globalnego .let
zmienne są łatwe w użyciu przy zamknięciach (nie powodują warunków wyścigu ).Ograniczenia nałożone przez
let
zmniejszają widoczność zmiennych i zwiększają prawdopodobieństwo wczesnego wykrycia nieoczekiwanych kolizji nazw. Ułatwia to śledzenie i uzasadnianie zmiennych, w tym ich osiągalności (pomoc w odzyskiwaniu nieużywanej pamięci).W związku z tym
let
zmienne rzadziej powodują problemy, gdy są używane w dużych programach lub gdy niezależnie opracowane ramy są łączone w nowy i nieoczekiwany sposób.var
może być nadal przydatny, jeśli masz pewność, że chcesz efektu pojedynczego wiązania podczas zamykania w pętli (# 5) lub do deklarowania zewnętrznych widocznych zmiennych globalnych w kodzie (# 4). Użycievar
do eksportu może zostać zastąpione, jeśliexport
migruje z miejsca transpilatora do podstawowego języka.Przykłady
1. Brak zastosowania poza najbliższym załączającym blokiem: ten blok kodu zgłosi błąd odniesienia, ponieważ drugie użycie
x
występuje poza blokiem, w którym jest zadeklarowane za pomocąlet
:Natomiast ten sam przykład z
var
dziełami.2. Nie używaj przed deklaracją:
ten blok kodu wyrzuci
ReferenceError
przed uruchomieniem kodu, ponieważx
jest używany przed zadeklarowaniem:W przeciwieństwie do tego samego przykładu z
var
analizami i uruchomieniami bez zgłaszania wyjątków.3. Brak ponownej deklaracji: Poniższy kod pokazuje, że zmienna zadeklarowana za pomocą
let
może nie zostać później ponownie zadeklarowana:4. Globały nieprzyłączone do
window
:5. Łatwość użycia z zamknięciami: Deklarowane zmienne
var
nie działają dobrze z zamknięciami wewnątrz pętli. Oto prosta pętla, która generuje ciąg wartości, które zmiennai
ma w różnych punktach czasowych:W szczególności wyniki te:
W JavaScript często używamy zmiennych znacznie później niż w momencie ich tworzenia. Kiedy wykażemy to, opóźniając wyjście o zamknięcie przekazane do
setTimeout
:... wynik pozostaje niezmieniony, dopóki trzymamy się
let
. Natomiast gdybyśmyvar i
zamiast tego użyli :... pętla nieoczekiwanie wyprowadza pięć razy „i ma 5”:
źródło
var
zamiastlet
, kod jest równoważny z:var i = 0; while (i < 5) { doSomethingLater(); i++; }
i
znajduje się poza zamknięciem, a do czasudoSomethingLater()
wykonaniai
został już zwiększony 5 razy, stąd wynik jesti is 5
pięć razy. Dzięki użyciulet
zmiennai
znajduje się w zamknięciu, więc każde wywołanie asynchroniczne otrzymuje własną kopięi
zamiast używać „globalnej”, która została utworzonavar
.for
. Bardziej dokładna transformacja, choć bardziej skomplikowana, to klasycznafor (var i = 0; i < 5; i++) { (function(j) { setTimeout(_ => console.log(
i to $ {j},), 125/*ms*/); })(i); }
która wprowadza „rekord aktywacji funkcji”, aby zapisać każdą wartośći
z nazwąj
wewnątrz funkcji.Niech następujące dwie funkcje pokazują różnicę:
źródło
let
jest interesujące, ponieważ pozwala nam zrobić coś takiego:Co powoduje zliczanie [0, 7].
Natomiast
Liczy się tylko [0, 1].
źródło
Funkcja VS zakres bloku:
Główna różnica między
var
ilet
polega na tym, że zmienne zadeklarowane za pomocąvar
mają zasięg działania . Natomiast funkcje zadeklarowane za pomocąlet
mają zasięg blokowy . Na przykład:zmienne z
var
:Gdy pierwsza funkcja
testVar
zostanie wywołana, zmienna foo, zadeklarowana za pomocąvar
, jest nadal dostępna pozaif
instrukcją. Ta zmiennafoo
byłaby dostępna wszędzie w zakresietestVar
funkcji .zmienne z
let
:Gdy druga funkcja
testLet
zostanie wywołana, pasek zmiennych, zadeklarowany za pomocąlet
, jest dostępny tylko wewnątrzif
instrukcji. Ponieważ zmienne zadeklarowanąlet
są bloku o zakresie (blok ma kod pomiędzy klamrami na przykładif{}
,for{}
,function{}
).let
zmienne nie są podnoszone:Kolejną różnicą pomiędzy
var
ilet
są zmienne z zadeklarowanym za pomocąlet
nie daj się podnieść . Przykład jest najlepszym sposobem zilustrowania tego zachowania:zmienne z
let
nie są podnoszone:zmienne z
var
do get hoisted:Globalny
let
nie przywiązuje się dowindow
:Zmienna zadeklarowana
let
w zakresie globalnym (który jest kodem, który nie jest funkcją) nie jest dodawana jako właściwośćwindow
obiektu globalnego . Na przykład (ten kod ma zasięg globalny):Użyj
let
nadvar
dowolnym momencie może dlatego, że jest po prostu scoped bardziej szczegółowe. Zmniejsza to potencjalne konflikty nazewnictwa, które mogą wystąpić w przypadku dużej liczby zmiennych.var
może być użyty, gdy chcesz, aby zmienna globalna była wyraźnie nawindow
obiekcie (zawsze dokładnie rozważ, czy jest to naprawdę konieczne).źródło
Wydaje się również, że przynajmniej w Visual Studio 2015, TypeScript 1.5, „var” dopuszcza wiele deklaracji o tej samej nazwie zmiennej w bloku, a „let” nie.
To nie wygeneruje błędu kompilacji:
Spowoduje to:
źródło
var
jest zmienną zasięgu globalnego (zdolną do podnoszenia).let
iconst
ma zakres blokowy.źródło
Podczas używania
let
let
Kluczowe przywiązuje deklaracji zmiennej do zakresu jakiegokolwiek bloku (powszechnie{ .. }
para) to zawarty w. Innymi słowy,let
w sposób dorozumiany hijacks zakres dowolny blok za jego deklaracji zmiennej.let
zmienne nie mogą być dostępne wwindow
obiekcie, ponieważ nie można uzyskać do nich globalnego dostępu.Podczas używania
var
var
a zmienne w ES5 mają zakresy funkcji, co oznacza, że zmienne są prawidłowe w obrębie funkcji, a nie poza samą funkcją.var
zmienne mogą być dostępne wwindow
obiekcie, ponieważ nie można uzyskać do nich globalnego dostępu.Jeśli chcesz dowiedzieć się więcej, czytaj dalej poniżej
jedno z najbardziej znanych pytań na temat zakresu wywiadu może również wystarczyć do dokładnego użycia
let
ivar
jak poniżej;Podczas używania
let
Dzieje się tak, ponieważ podczas używania
let
, dla każdej iteracji pętli zmienna ma zakres i ma swoją własną kopię.Podczas używania
var
Dzieje się tak, ponieważ podczas używania
var
, dla każdej iteracji pętli zmienna ma zakres i ma współdzieloną kopię.źródło
Jeśli dobrze przeczytam specyfikację, to na
let
szczęście można ją również wykorzystać, aby uniknąć wywoływania funkcji używanych do symulacji tylko prywatnych członków - popularny wzorzec projektowy, który zmniejsza czytelność kodu, komplikuje debugowanie, nie dodaje żadnej prawdziwej ochrony kodu ani innych korzyści - z wyjątkiem może zaspokojenia czyichś pragnienie semantyki, więc przestań go używać. /tyradaZobacz „ Emulowanie prywatnych interfejsów ”
źródło
let
? (Zakładam, że masz na myśli IIFE z „funkcją samodzielnego wywoływania”).hiddenProperty
w konstruktorze? Jest tylko jedenhiddenProperty
dla wszystkich instancji w twojej „klasie”.W najbardziej podstawowych terminach
⚡️ Piaskownica do zabawy ↓
źródło
Niektóre hacki z
let
:1.
2)
3)
Getter i seter z
let
:źródło
let { type, name, value } = node;
? tworzysz nowy obiekt z 3 właściwościami typ / nazwa / wartość i inicjujesz je wartościami właściwości z węzła?var
.let vs var. Chodzi o zakres .
Zmienne var są globalne i można uzyskać do nich dostęp praktycznie wszędzie, natomiast zmienne nie są globalne i istnieją tylko do momentu, gdy nawias zamykający je zabije.
Zobacz mój przykład poniżej i zauważ, jak zmienna lion (let) działa inaczej w dwóch console.logs; staje się poza zakresem w 2. konsoli.log.
źródło
źródło
let jest częścią es6. Funkcje te wyjaśnią różnicę w łatwy sposób.
źródło
Poniżej pokazano, jak różnią się zasięgiem „let” i „var”:
gfoo
, Zdefiniowane przezlet
początkowo znajduje się w zasięgu globalnym , a kiedy deklarujemygfoo
ponownie wewnątrzif clause
jego zakresu zmieniło i gdy nowa wartość jest przypisana do zmiennej wewnątrz tego zakresu to nie wpływa na zasięg globalny.Podczas gdy
hfoo
zdefiniowany przezvar
jest początkowo w zakresie globalnym , ale ponownie, kiedy deklarujemy go w zakresieif clause
, uwzględnia globalny zakres hfoo, chociaż var został ponownie użyty do jego zadeklarowania. Kiedy ponownie przypisujemy jego wartość, widzimy, że wpływa to również na globalny zasięg hfoo. To jest podstawowa różnica.źródło
Jak wspomniano powyżej:
Przykład 1:
W obu moich przykładach mam funkcję
myfunc
.myfunc
zawiera zmiennąmyvar
równą 10. W moim pierwszym przykładzie sprawdzam, czymyvar
równa się 10 (myvar==10
). Jeśli tak, deklaruję zmiennąmyvar
(teraz mam dwie zmienne myvar) za pomocąvar
słowa kluczowego i przypisuję jej nową wartość (20). W następnym wierszu wypisuję jego wartość na konsoli. Po bloku warunkowym ponownie wypisuję wartośćmyvar
na konsoli. Jeśli spojrzysz na wynikmyfunc
,myvar
ma wartość równą 20.Przykład 2: W moim drugim przykładzie zamiast użycia
var
słowa kluczowego w moim bloku warunkowym deklarujęmyvar
użycielet
słowa kluczowego. Teraz, kiedy dzwonięmyfunc
, otrzymuję dwa różne wyjścia:myvar=20
imyvar=10
.Różnica jest więc bardzo prosta, tzn. Jej zakres.
źródło
Chcę połączyć te słowa kluczowe z kontekstem wykonania, ponieważ kontekst wykonania jest ważny w tym wszystkim. Kontekst wykonania 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 fazy tworzenia kontekstu wykonania zmienne var, let i const będą nadal przechowywać zmienną w pamięci o nieokreślonej wartości w środowisku zmiennych danego kontekstu wykonania. Różnica polega na fazie wykonania. Jeśli użyjesz odwołania do zmiennej zdefiniowanej za pomocą var przed przypisaniem jej wartości, zostanie ona po prostu niezdefiniowana. Nie zostanie zgłoszony żaden wyjątek.
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, wyjątek zostanie zgłoszony podczas fazy wykonania kontekstu wykonania. Teraz zmienna nadal będzie w pamięci, dzięki fazie tworzenia kontekstu wykonania, ale silnik nie pozwoli jej użyć:
Jeśli zmienna jest zdefiniowana za pomocą var, jeśli aparat nie może znaleźć zmiennej w bieżącym środowisku zmiennym bieżącego kontekstu wykonania, przejdzie w górę łańcucha zasięgu (środowisko zewnętrzne) i sprawdzi zmienne środowisko środowiska zewnętrznego. Jeśli nie może go tam znaleźć, będzie kontynuował przeszukiwanie łańcucha zasięgu. Nie jest tak w przypadku let i const.
Drugą cechą let jest to, że wprowadza zakres bloków. Bloki są zdefiniowane przez nawiasy klamrowe. Przykłady obejmują bloki funkcyjne, jeśli bloki, dla bloków itp. Gdy deklarujesz zmienną z wpuszczeniem wewnątrz bloku, zmienna jest dostępna tylko wewnątrz bloku. W rzeczywistości za każdym razem, gdy blok jest uruchamiany, na przykład w pętli for, tworzy nową zmienną w pamięci.
ES6 wprowadza również słowo kluczowe const do deklarowania zmiennych. const ma również zasięg blokowy. Różnica między let i const polega na tym, że zmienne const muszą być deklarowane za pomocą inicjatora, w przeciwnym razie wygeneruje 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 wykonania będzie to obiekt okna w przeglądarkach. Nie jest tak w przypadku let lub const.
źródło
Myślę, że warunki i większość przykładów są nieco przytłaczające. Głównym problemem, jaki osobiście miałem z tą różnicą, jest zrozumienie, czym jest „Blok”. W pewnym momencie zdałem sobie sprawę, że blok będzie nawiasami klamrowymi oprócz
IF
instrukcji. otwierający nawias{
funkcji lub pętli definiuje nowy blok, wszystko zdefiniowanelet
w nim, nie będzie dostępny po zamykającym nawiasie}
tej samej rzeczy (funkcji lub pętli); Mając to na uwadze, łatwiej było zrozumieć:źródło
Teraz myślę, że lepiej jest scopować zmienne do bloku instrukcji, używając
let
:Myślę, że ludzie zaczną używać let tutaj, aby mieli podobne zakresy w JavaScript, jak inne języki, Java, C # itp.
Ludzie, którzy nie rozumieli dokładnie zakresu w JavaScript, wcześniej popełnili błąd.
Podnoszenie nie jest obsługiwane przy użyciu
let
.Przy takim podejściu błędy obecne w JavaScript są usuwane.
Zobacz ES6 In Depth: let i const, aby lepiej to zrozumieć.
źródło
W tym artykule wyraźnie określono różnicę między var, let i const
https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75#.esmkpbg9b
źródło