Czy zmienne deklarowane za pomocą let lub const nie są podnoszone w ES6?
Od jakiegoś czasu gram z ES6 i zauważyłem, że podczas gdy zmienne zadeklarowane z var
są podnoszone zgodnie z oczekiwaniami...
console.log(typeof name); // undefined
var name = "John";
...zmienne deklarowane przez let
lub const
wydają się mieć pewne problemy z podnoszeniem:
console.log(typeof name); // ReferenceError
let name = "John";
I
console.log(typeof name); // ReferenceError
const name = "John";
Czy to oznacza, że zmienne zadeklarowane przez let
lub const
nie są podnoszone? Co tu się naprawdę dzieje? Czy jest jakaś różnica między let
i const
w tej sprawie?
3 answers
@thefourtheye ma rację mówiąc, że te zmienne nie mogą być dostępne przed ich zadeklarowaniem. Jest to jednak nieco bardziej skomplikowane.
Czy zmienne deklarowane są przez
let
Czyconst
nie są podnoszone? Co tu się naprawdę dzieje?
Wszystkie deklaracje (var
, let
, const
, function
, function*
, class
) są "podnoszone" W JavaScript. Oznacza to, że jeśli nazwa jest zadeklarowana w zakresie, w tym zakresie identyfikator będzie zawsze odwołaj się do danej zmiennej:
x = "global";
// function scope:
(function() {
x; // not "global"
var/let/… x;
}());
// block scope (not for `var`s):
{
x; // not "global"
let/const/… x;
}
Jest to prawdą zarówno dla zakresów funkcyjnych, jak i blokowych1.
Różnica między var
/function
/function*
deklaracje i let
/const
/class
deklaracje są inicjalizacją .
Te pierwsze są inicjowane przez undefined
lub funkcję (generator) po utworzeniu powiązania na górze zakresu. Zmienne leksykalne pozostają jednak niezainicjalizowane. Oznacza to, że a ReferenceError
wyjątek jest wyrzucany, gdy próbujesz uzyskać do niego dostęp. Zostanie zainicjowany tylko wtedy, gdy let
/const
/class
twierdzenie jest oceniane, wszystko przed (powyżej), który jest nazywany temporal dead zone .
x = y = "global";
(function() {
x; // undefined
y; // Reference error: y is not defined
var x = "local";
let y = "local";
}());
Zauważ, że let y;
Instrukcja inicjalizuje zmienną undefined
tak jak let y = undefined;
.
Temporal dead zone nie jest miejscem składniowym, ale raczej czasem pomiędzy utworzeniem zmiennej (scope) a inicjalizacją. To nie jest błąd odwoływania się do zmiennej w kodzie nad deklaracją tak długo, jak ten kod nie jest wykonywany (np. ciało funkcji lub po prostu martwy kod), i spowoduje wyświetlenie wyjątku, jeśli uzyskasz dostęp do zmiennej przed inicjalizacją, nawet jeśli kod dostępu znajduje się poniżej deklaracji (np. w deklaracji funkcji podniesionej, która jest wywoływana zbyt wcześnie).
Nie, działają tak samo jak podnośniki / align = "left" / Jedyną różnicą między nimi jest to, że antCzy jest jakaś różnica między
let
iconst
w tej sprawie?
const
musi być i może być przypisany tylko w części inicjalizatora deklaracji (const one = 1;
, zarówno const one;
, jak i późniejsze przypisania, takie jak one = 2
są nieważne).
1: var
deklaracje nadal działają tylko na poziomie funkcji, oczywiście
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-11 14:28:42
Cytowanie specyfikacji ECMAScript 6 (ECMAScript 2015) , let
i const
deklaracje sekcja,
Zmienne są tworzone, gdy ich zawierające środowisko leksykalne jest instancjowane, ale nie mogą być dostępne w żaden sposób, dopóki nie zostanie ocenione Leksykalbinding zmiennej .
Więc, aby odpowiedzieć na twoje pytanie, tak, let
i const
hoist, ale nie możesz uzyskać do nich dostępu przed rzeczywistą deklaracją jest oceniana w czasie wykonywania.
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-22 14:50:57
ES6
wprowadza zmienne Let
, które pojawiają się z block level scoping
. Dopóki ES5
nie mieliśmy block level scoping
, więc zmienne zadeklarowane wewnątrz bloku są zawsze hoisted
do zakresu na poziomie funkcji.
Zasadniczo Scope
odnosi się do tego, gdzie w programie są widoczne Twoje zmienne, co określa, gdzie możesz używać zadeklarowanych zmiennych. W ES5
mamy global scope,function scope and try/catch scope
, z ES6
otrzymujemy również przeskalowanie poziomu bloku za pomocą Let.
- gdy zdefiniujesz zmienną za pomocą słowa kluczowego
var
znana jest cała funkcja od momentu jej zdefiniowania. -
Kiedy zdefiniujesz zmienną za pomocą instrukcji
let
jest ona znana tylko w bloku, który jest zdefiniowany.function doSomething(arr){ //i is known here but undefined //j is not known here console.log(i); console.log(j); for(var i=0; i<arr.length; i++){ //i is known here } //i is known here //j is not known here console.log(i); console.log(j); for(let j=0; j<arr.length; j++){ //j is known here } //i is known here //j is not known here console.log(i); console.log(j); } doSomething(["Thalaivar", "Vinoth", "Kabali", "Dinesh"]);
Jeśli uruchomisz kod, zobaczysz, że zmienna {[15] } jest znana tylko w loop
, a nie przed i po. Jednak nasza zmienna {[17] } jest znana w entire function
od momentu jej zdefiniowania.
Jest jeszcze jedna wielka zaleta za pomocą let, ponieważ tworzy nowe środowisko leksykalne, a także wiąże świeżą wartość zamiast zachowywania starego odniesienia.
for(var i=1; i<6; i++){
setTimeout(function(){
console.log(i);
},1000)
}
for(let i=1; i<6; i++){
setTimeout(function(){
console.log(i);
},1000)
}
Pierwsza pętla for
zawsze wypisuje ostatnią wartość, z let
tworzy nowy zakres i binduje nowe wartości druk us 1, 2, 3, 4, 5
.
Idąc do constants
, Działa w zasadzie jak let
, jedyna różnica polega na tym, że ich wartości nie można zmienić. W stałych mutacja jest dozwolona, ale zmiana przypisania nie jest dozwolona.
const foo = {};
foo.bar = 42;
console.log(foo.bar); //works
const name = []
name.push("Vinoth");
console.log(name); //works
const age = 100;
age = 20; //Throws Uncaught TypeError: Assignment to constant variable.
console.log(age);
Jeśli stała odnosi się do object
, zawsze będzie odnosić się do object
, ale sama object
może być zmieniona (jeśli jest zmienna). Jeśli chcesz mieć niezmienny object
, możesz użyć Object.freeze([])
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-11 06:46:36