Variables
Var
Before ES6, the way to declare a variable was using the var
keyword.
var foo = 'bar'
Not only the reference of a var
variable can be changed but the variable itself can be redeclared.
var foo = 'bar'
foo = "rab"
foo // => "rab"
var foo = 42
foo // => 42
Function Scoping of Var
Variables declared with the var
keyword are function scoped
therefore - unless being declared in the global scope - they are only available within the scope of functions in which they are declared.
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
Hoisting Var
var
variables - irrespective of where in a given scope are declared - are hoisted before code execution i.e. moved to the beginning of the scope and initialized with a value of undefined
.
function logVar() {
console.log(foo)
var foo = 'bar'
console.log(foo)
}
logVar() // undefined "bar"
Let
In addition to var
ES6 introduced let
and const
keywords. let
allows for defining variables, and const
for defining constants.
Reference of both - a var
variable and a let
variable - can be changed but the let
variable - as opposed to the var
variable - cannot be redeclared.
let foo = 'bar'
foo = 'rab'
foo // => "rab"
let foo = 42 // Uncaught SyntaxError: Identifier 'foo' has already been declared
Block (aka Lexical, aka Static) Scoping of Let
A variable declared with let
is not function scoped like var
but block scoped. It means that a separate scope for let
variable does not only exist within a global scope, within a function scope but also within a block scope.
let foo = 'bar'
if (true) {
let foo = 'rab'
}
console.log(foo) // "bar"
Const
ES6 introduced the possibility of declaring constants with a const
keyword.
Not only constants cannot be redeclared but also their references cannot be changed. Although, a reference of a once declared constant cannot change that does not mean that the referenced value is not allowed to change.
const foo = 'bar'
foo = 'rab' // Uncaught TypeError: Assignment to constant variable.
const foobar = { a: 1 }
foobar.a = 2
foobar // { a: 2 }
Constants - just like variables declared with let
- are lexically scoped.