Var keyword declares a variable which is scoped to its current execution context, optionally initializing to a value.
Let keyword declares a block-scoped variable, optionally initializing it to a value.
Const keyword declares constants which are block scoped much like variables defined using let but the value of a constant cannot change. The const declaration creates a read-only reference to a value.
Conceptually, hoisting suggests that variables and function declarations are physically moved to the top of your code. Technically, what happens is that the variable and function declarations are put into memory during the compilation phase but stay exactly where you typed them in your code. The primary importance of hoisting is that it allows you to use functions before you declare them in your code.
The key things to take out of the definition for hoisting are
What gets moved around is variable and function declarations. Variable assignments or initialization are never moved around.
The declarations are not exactly moved to the top of your code; instead, they are put into memory.
However, variables defined with let or const keywords when hoisted are not initialized with a value of undefined. Rather, they are in a state called the Temporal Dead Zone and are not initialized until their definitions are evaluated.
The next code snippet demonstrates the hoisting of let and const variables.
The x variable defined with let keyword in the block is hoisted and takes precedence over the x variable defined with var. However, it is still in the temporal dead zone when it’s referenced in console.log(x) and so throws a reference error.
Variables defined with the var keyword have a scope that is its current execution context. They are not block scoped and so can be accessed from outside the block they were defined, provided it’s still within the scope of its execution context. Let and const variables, however, are block scoped and cannot be accessed from outside the block. This concept is shown below
Also, when you declare a global variable with var keyword, the variable gets attached to the global context (window in the browser and global in node). This is not the case with global variables declared with let and const.
- When you don’t declare a variable but assign a value to the variable, the variable gets created and is attached to the global execution context (window in the browser and global in node). This, however, is strongly advised against as it makes debugging very difficult.
- Variables declared with var keyword can be redeclared at any point in the code even within the same execution context. This is not the case for variables defined with let and const keywords as they can only be declared once within their lexical scope.
This can especially cause a problem if you use let or const to declare a variable in multiple switch cases.
Of course, it can be avoided by using curly braces around the cases to define different blocks, but this should probably be refactored.
- Another gotcha to remember about constants is that even though its value cannot be reassigned to, it is still mutable. The behavior can be seen in the fact that if the value is an object, the object’s properties can be modified.
So yeah that pretty much sums up the definitions and gotchas with using either of the variable declaration methods.