JavaScript, like a lot of more modern languages, provides a host of different methods for variable declaration. JavaScript has the var, let and const keywords for variable declarations and with each comes a different use case. This article aims to dive in-depth into the caveats and nuances which you might encounter when using either of these variable declaration methods.
For a bit more context, see the definitions of each of the keywords as defined in the official ECMAScript specifications and MDN.
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.
HOISTING
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.
In JavaScript, all variables defined with the var keyword have an initial value of undefined. This is due to hoisting which puts the variable declarations in memory and initializes them with the value of undefined. This behavior can be shown with the following example
line 2 throws a ReferenceError: y is not defined
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.
line 1 throws ReferenceError because it is still in Temporal Dead Zone
The next code snippet demonstrates the hoisting of let and const variables.
line 3 throws a ReferenceError because x in line 4 has been hoisted within the block
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.
SCOPE
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
some variables are referenced outside of their scope
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.
GOTCHAS
- 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.
the variables get attached to the global context
- 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.
cannot redeclare let and const variables.
This can especially cause a problem if you use let or const to declare a variable in multiple switch cases.
foo in both cases reside in the same block scope
Of course, it can be avoided by using curly braces around the cases to define different blocks, but this should probably be refactored.
foo in both cases reside in different block scopes
- 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.
variables defined with const are still mutable.
So yeah that pretty much sums up the definitions and gotchas with using either of the variable declaration methods.
Top comments (0)