What's the difference between using `let` and `var` in Javascript?
As I know both let
and var
are local variables, however, I'm as yet not exactly sure what is the difference between both.
So, please explain What are the differences? When should I use let
instead of var
?
Here are few differences between using let
and var
:
1. Redeclaration:
In strict mode, var
will let you re-declare the same variable in the same scope while let
throws a SyntaxError
.
'use strict';
var foo = "foo1";
var foo = "foo2"; // No problem, 'foo' is replaced.
let bar = "bar1";
let bar = "bar2"; // SyntaxError: Identifier 'bar' has already been declared
2. Creating global object property:
let
, in contrast to var
, doesn't make a property on the global object:
var foo = "Foo"; // globally scoped
let bar = "Bar"; // globally scoped
console.log(window.foo); // Foo
console.log(window.bar); // undefined
3. Scoping rules:
The most important difference is the scoping rules. Variables declared by var
keyword are scoped to the immediate function body while let
variables are scoped to the immediate enclosing block meant by { }
.
function run() {
var foo = "Foo";
let bar = "Bar";
console.log(foo, bar); // Foo Bar
{
let baz = "Bazz";
console.log(baz); // Bazz
}
console.log(baz); // ReferenceError
}
run();
The motivation behind why let keyword was introduced with the language was function scope is confusing and was one of the main sources of bugs in JavaScript.
var funcs = [];
// let's create 3 functions
for (var i = 0; i < 3; i++) {
// and store them in funcs
funcs[i] = function() {
// each should log its value.
console.log("Value: " + i);
};
}
for (var j = 0; j < 3; j++) {
// and now let's run each one to see
funcs[j]();
}
Value: 3
was output to console each time funcs[j]();
was used since anonymous functions were bound to the same variable.
Developers needed to make immediately invoked functions to catch correct value from the loops yet that was also hairy.
4. Hoisting:
While variables declared with var
keyword are hoisted (initialized with undefined before the code is run) which implies they are accessible in their enclosing scope even before they are declared:
function run() {
console.log(foo); // undefined
var foo = "Foo";
console.log(foo); // Foo
}
run();
let
variables are not initialized until their definition is evaluated. Accessing them before the initialization brings about a ReferenceError
. Variable said to be in "temporal dead zone" from the beginning of the block until the initialization is handled.
function checkHoisting() {
console.log(foo); // ReferenceError
let foo = "Foo";
console.log(foo); // Foo
}
checkHoisting();
-
var
statement is known throughout the function it is defined in, from the start of the function. -
let
statement is only known in the block it is defined in, from the moment it is defined onward.
To understand the difference, consider the following code:
// i IS NOT known here
// j IS NOT known here
// k IS known here, but undefined
// l IS NOT known here
function loop(arr) {
// i IS known here, but undefined
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
for( var i = 0; i < arr.length; i++ ) {
// i IS known here, and has a value
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
};
// i IS known here, and has a value
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
for( let j = 0; j < arr.length; j++ ) {
// i IS known here, and has a value
// j IS known here, and has a value
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
};
// i IS known here, and has a value
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
}
loop([1,2,3,4]);
for( var k = 0; k < arr.length; k++ ) {
// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS NOT known here
};
for( let l = 0; l < arr.length; l++ ) {
// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS known here, and has a value
};
loop([1,2,3,4]);
// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS NOT known here
Please login or create new account to participate in this conversation.