In JavaScript, we need to declare variables. There are three ways to declare variables using the keywords var, let, and const. However, what are the differences, and when should we use each one? Why shouldn't we recommend using var?
Let's discuss.
Var:
To understand var
, it's important to know about a global object. In browsers, there is a global object named window
. First, let's take a look at the window object
.
Characteristics of var
:
- Variables declared using
var
work in both global and function scope. var
variables can be re-declared.var
variables can be reassigned.var
variables can hoisted.
Let's now declare a variable using the var
keyword.
var a = 10;
var b = "hello";
function test1() {}
var test2 = () => {};
When we declare a variable using var
, outside any function, it gets appended to the window
object. So, after declaring a variable using var, if we log window, we can see that it contains the variable.
What we can understand from that example is that var
works as a global variable declaration. When we declare a variable using var, it is set as a global scope variable, meaning it becomes a property of the global object (window
in the case of browsers). This can lead to unintended consequences and potential issues with variable scoping and accidental variable reassignment.
What is scope?
Scope refers to the context in which variables are defined and can be accessed. It determines the visibility and lifetime of variables within a program.
Var
problems with scope:
So declaring a variable with var
, it works in global scope and function scope, but it has no effect on block scope.
var message = "First message";
if (true) {
var message = "Second message";
}
console.log(message); // "Second message"
In the above example, when we declare the message variable within the if block, it actually overrides the global variable window.message
.
Var problems with reassignment:
At times, when we want to keep certain values fixed, like the value of PI. But when using var, these values might accidentally get changed or overwritten, which can be risky.
var valueOfPI = 3.1416;
console.log(valueOfPI); // 3.1416
/*
Other codes
-- ---- - ----
----------------
---
---------
---------------------
*/
/*
Other codes
-- ---- - ----
-------
---
------
*/
valueOfPI = 99;
console.log(valueOfPI); // 99
Var problems with re-declaration :
Again when we use var
we can redeclare a variable with the same name.
var message = "Message A";
console.log(message); // "Message A"
var message = "Message B";
console.log(message); // "Message B"
var message = "Message C";
console.log(message); // "Message C"
This situation can make the code-base riskier because in a lengthy code-base, variable modifications like this may occur without throwing any errors, making debugging more complex.
Var problems with hoisting :
Hoisting is a term in JavaScript where all variable and function declarations within a scope are moved to the top of that scope. In the case of var
, variables are declared with the value undefined
.
console.log(message); // undefined
var message = "hello with var";
It works like:
var message = undefined;
console.log(message); // undefined
message = "hello with var";
Accessing a variable its before declaration indeed lead to confusing and weird behavior during the execution. And var
don't have any Temporal Dead Zone (TDZ) like let
or const
.
Q: Is there any way to use var as block scope?
The direct answer is no, you can't directly achieve block-scoping with var. However, you can achieve it indirectly by using Immediately-Invoked Function Expressions (IIFE).
An IIFE is a type of function that is created and invoked immediately after its creation.
After wrapping var
variables in an IIFE, they behave as if they are in block scope. If we try to access these variables outside the IIFE, it will throw a ReferenceError
.
// IIFE using arrow function
(() => {
var a = 10;
console.log(a); // 10
})();
console.log(a); // ReferenceError: a is not defined
// IIFE using traditional function
(function () {
var b = 10;
console.log(b); // 10
})();
console.log(b); // ReferenceError: a is not defined
As we know, var
is function-scoped. To achieve block scope functionality, we create a function and immediately invoke it. As a result, all variables and functions within that Immediately-Invoked Function Expression (IIFE) will only exist within its scope, and we can't access them outside of that function. This creates a block scope illusion.
Conclusion:
To solve all these problems, ES6 introduced two new ways to declare variables: let and const, which are safer than var.
Thanks for reading. If this information is helpful to you, please consider following me. If you have any questions or would like to discuss any other topic related to web development or JavaScript, feel free to comment below.