Function Scope and Block Scope

Whenever you declare a variable inside a function, the variable is bound within the function and you can’t access it outside the function. var is the keyword to define a variable for function-scope accessibility.

Now, you might ask, if it gives an error even if you use let or const , why is only var associated with function scope? The thing is, let and const are used to define block scope, and before ES6, JavaScript didn't have block scope or let and const .

A block scope is the area within if , switch conditions or for and while loops. Simply put , whenever you see {curly brackets}, it is a block.

Let's see an example:

Now you might expect that none of the log commands should work but as you can see that is not the case with var, variables defined with var inside if , switch conditions or for and while loops can be accessed globally and are part of global scope and hence it is better practice to use let and const with them.

Lexical Scope

Finally, we have reached the true purpose of this post. Well, I could have skipped the long discussion of scope but personally, I don’t think you can understand lexical scope without knowing the key components revolving around it.

Again, a point to remember: Javascript has lexical scoping with functions scope.

In simple words, it means the children scope has access to the variables defined in the parent scope. For instance, If I were to define a function and declare a variable inside it and inside the very same function, define another function, then I should be able to use that variable inside the inner function because of lexical scoping. Let's see an example:

It can be seen from the example, the variables declared in outerFunction() are accessed by innerfunction() , this is lexical scoping.

The scope of variables is defined by their position in the code. In order to resolve variables, JavaScript starts at the innermost scope and searches outwards until it finds the variable it was looking for. In the above example, Javascript first searches for variables inside innerFunction() and when it doesn’t find it, it goes outside i.e outerFunction()

Lexical scoping is better because we can easily figure out the value of a variable from the code, whereas in dynamic scoping, the meaning of a variable can change at runtime, which makes it complex to understand.

So, we have successfully understood what lexical scoping is, now let’s look at closures where lexical scoping is actually used.