ES6  – let + const

javascript

Pierwszy temat związany z nadchodzącym ECMAScript 2015, czyli letconst. Oba pojęcia bardzo mocno związane są ze scope deklarowanych zmiennych, co postaram się pokazać w porównaniu ze sposobem deklaracji zmiennych za pomocą słowa kluczowego var.


Zobacz całą serię: Let-s talk about ECMAScript 2015


Spójrzmy wpierw jednak na przykład pokazujący użycie var i deklaracji zmiennych znanych z ES5 i wcześniej.

var a = 1;
 
if (1 === a) {
 var b = 2; 
}
 
for (var c = 0; c < 3; c++) {
 // …
}
 
function letsDeclareAnotherOne() {
 var d = 4;
}
 
console.log(a); // 1
console.log(b); // 2
console.log(c); // 3
console.log(d); // ReferenceError: d is not defined
 
// window
console.log(window.a); // 1
console.log(window.b); // 2
console.log(window.c); // 3
console.log(window.d); // undefined
  1. Zmienna a deklarowana jest jako globalna.
  2. Zmienna b deklarowana jest wprawdzie wewnątrz bloku if, ale jest ona również widoczna poza nim.
  3. Podobnie jak deklaracja b, zmienna c deklarowana jest w bloku for, który nie ogranicza jej swoim zasięgiem.
  4. Dopiero zmienna d posiada swój własny scope, ponieważ ograniczona jest ciałem funkcji.
Variables in JavaScript are hoisted to the top!

Hoisting, to w JavaScript domyślne zachowanie w momencie deklaracji zmiennych = wynoszenie dekleracji na samą górę skryptu lub ciała funkcji.

Tym samym zmienna w języku JavaScript może być użyta zanim zostanie zainicjalizowana. Różnicę w dekleracji zmiennych, a ich inicjalizacji przedstawia poniższy przykład:

var n = 1;
 
(function () {
 console.log(n);
 var n = 2;
 console.log(n);
})();
 
console.log(n);

let

Spójrzmy teraz na nowy sposób deklaracji zmiennych, który bezpośrednio wpływa na ich zakres działania.

let a = 1;
 
if (1 === a) {
 let b = 2; 
}
 
for (let c = 0; c < 3; c++) {
 // …
}
 
function letsDeclareAnotherOne() {
 let d = 4;
}
 
console.log(a); // 1
console.log(b); // ReferenceError: b is not defined
console.log(c); // ReferenceError: c is not defined
console.log(d); // ReferenceError: d is not defined
 
// window
console.log(window.a); // 1
console.log(window.b); // undefined
console.log(window.c); // undefined
console.log(window.d); // undefined

Jest to ten sam przykład kodu, który podawałem wyżej dla ES5. Tym razem jednak widzimy różnice w wartościach, które otrzymamy w konsoli przeglądarki. Tylko zmienna a zadeklarowana została jako globalne, a wszystkie pozostałe mają zasięg blokowy.

const

W przypadku użycia const otrzymamy dokładnie takie same wyniki jak dla deklaracji zmiennych z użyciem słowa kluczowego let. const tym samym również pozwala deklarować zmienne o zasięgu blokowym. Różni się jednak od let (i var również) tym, że raz zainicjalizowana wartość zmiennej nie może zostać nadpisana. Można było się tego domyślać po nazwie const (stała).

{
 const PI = 3.141593;
 PI = 3.14; // throws “PI” is read-only
}
 
console.log(PI); // throws ReferenceError: PI is not defined

Każda próba nadpisania zmiennej utworzonej za pomocą słówka const skończy się rzuceniem wyjątku przez interpeter JavaScript.

Powyższy przykład w ES5 mógłby wyglądać następująco:

var PI = (function () {
 var PI = 3.141593;
 return function () { return PI; };
})();