Zmienne
Var
Przed ES6 sposobem deklaracji zmiennej było używanie słowa kluczowego var
.
var foo = 'bar'
Nie tylko referencja zmiennej var
może ulec zmianie, ale nawet sama zmienna moż być ponownie zadeklarowana.
var foo = 'bar'
foo = "rab"
foo // => "rab"
var foo = 42
foo // => 42
Funkcyjny zakres Var
Zmienne deklarowane przy użyciu słowa kluczowego var
mają zakres funckji
, a więc - chyba, że są zadeklarowane w zakresie globalnym - są wyłącznie dostępne w zakresie funkcji, w ramach, której zostały zadeklarowane.
var foo = 'bar'
function logFoo() {
var foo = 'rab'
console.log(foo)
}
console.log(logFoo()) // "rab"
console.log(foo) // "bar"
if (true) {
var foo = '42'
}
console.log(foo) // 42
Podciąganie (ang. hoisting) Var
Zmienne var
- niezależnie od tego w jakim zakresie zostały zadeklarowane - są podciągane (ang. hoisted) przed wykonaniem codu, tzn. przenoszone na początek zakresu i inicjalizowane z wartością undefined
.
function logVar() {
console.log(foo)
var foo = 'bar'
console.log(foo)
}
logVar() // undefined "bar"
Let
W dodatku do var
ES6 wprowadził słowa kluczowe let
oraz const
. let
umożliwia definiowanie zmiennych, a const
stałych.
Wartość referowana przez obie - zmienną var
oraz zmienną let
- może ulec zmianie, ale zmienna let
- w przeciwieństwie do zmiennej var
- nie może być ponownie zadeklarowana.
let foo = 'bar'
foo = 'rab'
foo // => "rab"
let foo = 42 // Uncaught SyntaxError: Identifier 'foo' has already been declared
Blokowe (aka leksykalne, aka statyczne) zakresowanie let
Zmienna zadeklarowana z let
nie ma zakresu funkcyjnego, tak jak zmienna zadeklarowana z var
, a zakres blokowy. Oznacza to, że dla zmiennych zadeklarowanych z let
istnieje nie tylko oddzielny zakres globalny, oddzielny zakres funkcyjny, ale również oddzielny zakres w ramach danego bloku.
let foo = 'bar'
if (true) {
let foo = 'rab'
}
console.log(foo) // "bar"
Const
ES6 wprowadziło możliwość deklarowania stałych używając słowa kluczowego const
.
Nie tylko stałe nie mogą zostać ponownie zadeklarowane, ale również ich referencje nie mogą się zmienić. Pomimo tego, że referencja raz zadeklarowanej stałej nie może się zmienić, to nie oznacza to, że referowana wartość nie może ulec zmianie.
const foo = 'bar'
foo = 'rab' // Uncaught TypeError: Assignment to constant variable.
const foobar = { a: 1 }
foobar.a = 2
foobar // { a: 2 }
Stałe - tak jak zmienne deklarowane przy użyciu let
- mają zakres leksykalny.