Typically, JavaScript developers use var keyword to define variables. But that is not the only way to declare and define variables. In fact, starting ES6 in 2015, developers can also use let and const keywords to define variables. But many developers are not sure how they work, how they differ from var keyword and when to use them. In this article, we will learn about the difference between let and var in JavaScript.
What is Var Keyword
Since early days, JavaScript has allowed us to define variables using var keyword. Once you define a variable using var keyword, its scope is global and is accessible throughout the JavaScript file. Often, it is also used within a function for function scoping of variables. So if you happen to redeclare this variable anywhere inside or outside function, then it will be redefined everywhere else. This poses a problem especially in large JavaScript files which may access a variable from multiple points. That is where let keyword comes in.
What is Let Keyword
Let keyword allows you to declare block-scoped variables that can be re-assigned. But they must be declared before use, else they will give error. Also they cannot be redeclared inside the same block.
Difference Between Let and Var in JavaScript
There are several key differences between let and var keywords in JavaScript. Let us look at them one by one, in detail.
Scoping
One of the most important differences between let and var is their scoping rules. Var declared variables are scoped to the function where they are defined. Let declared variables are scoped to the immediate code block, that is, within curly braces ‘{…}’. The reason why let and const keywords were introduced is to support block scoping, as opposed to function or global scoping available with var keyword.
Here is an example to illustrate their difference.
function a(){
var b=1;
let c=2;
console.log(b,c); // output is 1 2
{
var d=3;
let e=4;
console.log(d,e); // output is 3 4
}
console.log(d); // output is 3
console.log(e); // ReferenceError
}
a()
In the above code, we defined a function a(). In it, we first defined variables b using var keyword and c using let keyword. They are both accessible inside the function scope. Then we create a code block inside the function. In it, we define variable d using var keyword and e using let keyword. They are both accessible within the code block. But when we try to access them outside the code block, variable d is accessible but variable e gives an error. This shows that let keyword has block scope and var keyword has function scope.
Global Object Property / Outside Function
You will also see that both var and let keywords can be used to create globally scoped variables, but the variables declared using let will not be a part of the global object. This is a very subtle difference. Here is an example to illustrate it.
var a = 1; // globally scoped
let b = 2; // globally scoped but not part of the global object
console.log(window.a); // 1
console.log(window.b); // undefined
In the above code, we declare both variables a and b as global variables, using var and let keywords respectively. But only variable a is accessible using global object property window.a.
Similarly, you cannot access globally scoped variables declared using let keyword, with this object either.
var a=1;
let b=2;
console.log(a); // 1
console.log(b); // 2
console.log(this.a); // 1
console.log(this.b); // undefined
Inside Function
Variables declared using var and let that are both inside a function but outside a code block, have the same scope and behave in a similar manner.
function test(){
var a=1;
var b=2;
console.log(a);
console.log(b);
}
test(); // output is 1 2
console.log(a); // ReferenceError: a is not defined
console.log(b); // ReferenceError: b is not defined
In the above code, both variables a and b are defined inside the function but not within any code block {…}. So they are both inaccessible outside the function and throw ReferenceError when we try to access either of them outside the function.
Inside Block
In this case, a variable declared using let keyword cannot be accessed outside the block. On the other hand, a variable declared using var keyword is accessible even outside the block.
{
var a=1;
let b=2;
}
console.log(a); // output is 1
console.log(b); // ReferenceError: b is not defined
In the above code, when we try to access variable b declared using let keyword, it throws a ReferenceError.
Inside Loop
Similarly, variables declared using let keyword in a loop are accessible only inside the loop. On the other hand, variables declared using var keyword are accessible outside also.
for (var i = 0; i < 3; i++) {
var j = i * 2;
}
console.log(i); // 3
console.log(j); // 4
for (let k = 0; k < 3; k++) {
let l = k * 2;
}
console.log(k); // ReferenceError: k is not defined
console.log(l); // ReferenceError: l is not defined
In the above code, neither of the two variable l or k, declared using let keyword, in the for loop, are accessible outside the loop.
Loops with closures
JavaScript Closures are combination of function with its surrounding state information (generally parent function) even after the parent has stopped execution. This allows you to implement state persistence in functions. When you use let keyword in a loop, in each iteration, you get a new variable. This is not the case when using var keyword. So you can safely use let keyword in closures.
// output is 3 3 3
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0);
}
// output is 0 1 2
for (let j = 0; j < 3; j++) {
setTimeout(() => console.log(j), 0);
}
In the above code, when we use let keyword, the for loop will display the counter values correctly. This indicates that let keyword is suitable for closures. But when we use var keyword, then each iteration will generate a new variable in every iteration.
Hoisting
Hoisting is the default behavior of JavaScript whereby all variable declarations are moved to the top of present scope. This can be to the top of the script or function where they are defined. This allows you to access variables even before they are explicitly initialized.
Variables declared using var keyword are hoisted as well as initialized. Their value will be undefined if they are accessed before their initialization statement is executed. But your code will not throw an error and terminate execution.
function test() {
console.log(a); // undefined
var a = 1;
console.log(a); // 1
}
test();
In the above code, we declare variable a using var keyword. We display its output before as well after initialization. The first time it returns undefined value and the second time it displays initialized value.
When you declare variable using let keyword, then it is hoisted but not initialized until its initialization is actually executed. In this case, if you access them before initialization, then it will throw a ReferenceError and stop execution.
function test() {
console.log(a); // ReferenceError: a is not defined
var a = 1;
console.log(a); // 1
}
test();
Re-declaration
You can always re-declare a variable that was declared using var, within the same scope. But you cannot re-declare a variable that was declared using let, within the same scope. It will give a SyntaxError.
You cannot re-declare a variable that was declared using var keyword, using let keyword. It will also give SyntaxError. Similarly, you cannot re-declare a variable that was declared using let keyword, using var keyword. It will give SyntaxError.
var a;
var a; // No error or warning
let b;
let b; // SyntaxError: Identifier 'b' has already been declared
var c;
let c; // SyntaxError: Identifier 'c' has already been declared
let d;
var d; // SyntaxError: Identifier 'd' has already been declared
Temporal Dead Zone
In JavaScript, a temporal dead zone is an area of code where the variable exists but is not accessible unless it is initialized. Due to this feature, variables declared using let keyword cannot be accessed before they are declared. Here is an example to demonstrate it.
console.log(a); // undefined
var a = 1;
console.log(b); // ReferenceError: b is not defined
let b = 2;
In the above code, we have two variables a and b declared using var and let keywords respectively. They are both accessed before they are initialized. The variable declared using var keyword returns undefined result whereas the variable defined using let keyword will throw a ReferenceError.
Comparison Between Let vs Var
Now that we have a good understanding of how var and let keywords work, let us quickly go through the key differences between them.
let | var |
syntax: let variable_name = value | syntax: var variable_name = value |
Accessible within the code block {…} where they are declared | Accessible within the function where they are declared, or globally if declared outside all functions. |
Cannot be redeclared within the same scope | Can be redeclared within the same function scope. |
Hoisted but not initialized. Throws ReferenceError if accessed before initialization. | Hoisted and initialized by default. Will return undefined value if accessed before initialization statement is executed. |
Available since ECMA Script 6 | Available since ECMA Script 1, since beginning. |
Supported by most modern web browsers | Supported by all web browsers |
Can be used with JavaScript closures | Difficult to use with JavaScript closures |
Not part of global object property, even if you declare let variables globally. | Part of global object property, if you declare var variable globally. |
Conclusion
In this article, we have learnt about the detailed differences between let and var keywords in JavaScript. You can use either of them depending on your situation. Variables declared using let keyword are accessible within the scope of code block and cannot be re-declared within the same block. Variables declared using var keyword are accessible within their function block or global space. They can be re-declared within the same function or global scope.
FAQ
1. Are var and let keywords interchangeable?
No. var keyword should be used for function scoping and let keyword should be used for block scoping of variables.
2. Can I re-declare a var declared variable as let variable? Or vice versa?
No. A var variable can be re-declared as var variable. If you re-declare a var variable as let variable or vice versa, you will get SyntaxError.
3. What is the advantage of let over var?
Let keyword allows you block specific scoping. It allows you to prevent accidental creation of global scope variables, since they have more restrictive scope than var variables.
4. What is the advantage of var over let?
Variables declared using var keyword are available throughout the function where they are defined. If you define them as global variables, then they are also available in global scope.
5. What are the disadvantages of let keyword?
Let keyword has limited scope compared to those declared using var. Also, they tend to give ReferenceError and SyntaxError if they are not used properly. Variables declared using var may very often return undefined value and continue execution, instead of throwing an error and terminating execution.
6. What are the disadvantages of var keyword?
Since var keyword has a wide scope, it can cause problems especially in large scripts. Also, since they can be easily re-declared, it can have unpredictable values if it is being modified by multiple parts of your script.
7. When to use let keyword?
Let keyword should be used if you want to assign block level variable scope, that can be reassigned multiple times. Secondly, they are great for using in closures and preserving function state.
8. When to use var keyword?
Var keyword is widely used by JavaScript developers. It can be used if you want your variables to have a global scope or function scope. They are also great if you want to re-declare them.
Also read:
How to Add Table Row in jQuery
How to Disable/Enable Input in jQuery
How to Disable Resizable Property of TextArea
Sreeram Sreenivasan is the Founder of Ubiq. He has helped many Fortune 500 companies in the areas of BI & software development.