In Javascript, code blocks are created using curly braces ({}). For example:
someFunction() {
// some code here
}
anotherFunction() {
// some more code here
}
someFunction
and anotherFunction
are two different code blocks. These two different code blocks could also be considered as two different scopes. What that means is that the variables declared in someFunction
only affect that block of code, and those declared in anotherFunction
only affect that block of code. They are "scoped" in that sense. To illustrate:
var name = "Kenny"
someFunction() {
var name = "Kyle"
console.log("someFunction block:", name) // someFunction block: Kyle
}
anotherFunction() {
var name = "Timmy"
console.log("anotherFunction block:", name) // anotherFunction block: Timmy
}
console.log("global", name) // global Kenny
As you can see, the same variable name
retains its global value although it gets redefined within someFunction
and anotherFunction
.
Now here is where it can get a bit tricky. With that knowledge in mind, it is easy to assume that this would always be the case whenever we have code blocks. Except, it doesn't work the same with if/else
statements and for
loops.
var name = "Kenny";
if (name) {
var name = "Kyle";
console.log("if block:", name); // if block: Kyle
}
console.log("global", name); // global Kyle
The name
variable inside the if
block resets the value of name
. The same happens in a for
loop:
var name = "Kenny";
for (var i = 0; i < 1; i++) {
var name = "Kyle";
console.log("for loop block:", name); // for loop block: Kyle
}
console.log("global", name); // global Kyle
The solution is to use the let
keyword instead of var
.
var name = "Kenny";
if (name) {
let name = "Kyle";
console.log("if block:", name); // if block: Kyle
}
console.log("global", name); // global Kenny
var name = "Kenny";
for (var i = 0; i < 1; i++) {
let name = "Kyle";
console.log("for loop block:", name); // for loop block: Kyle
}
console.log("global", name); // global Kenny
Top comments (4)
Apart from explaining lexical scope, this is also a great example to show why you must never use
var
.var
andlet
have different scoping rules, and as suchlet
is always bound to the block scope, which includes conditionals and loop blocks also.For a newbie Javascript programmer, it is much easier to understand that a variable declared with
let
always references the variable in the closest block scope where it is defined in.Things get crazy pretty quickly when it comes to scope and context, which is why most libraries / eslint rules enforce
const
usage and discourage mutating.Yeah.. Very helpful thanks.
I'm glad you found this helpful