Imagine you go out to an ICE CREAM shop and buy two scoops of ICE CREAM. How would you feel if a random person in the shop takes a bite off your ICE CREAM without your permission? Or the owner of the ICE CREAM shop mixes up your order and gives you the wrong one by mistake. You wouldn’t want that to happen to you, right? Because it is not going to feel right. Unless you decide to share no one should have access to it. Because at the end of the day you paid for it and it’s yours. On the other hand you can not tell the ICE CREAM shop to make ICE CREAM available for sale to the public.Because it’s not yours. But as long as it is available to the public, you can get it as well. Of course if you can pay for it. What does this got to do with the concept of Scope? Well, it demonstrates how the accessibility of a product is determined by ownership of the product. In the same token, accessibility of variables is determined by scope.
- Global Scope
- This is default enclosure and one that contains all the code including the local scope created by functions
- Function or local scope
- This is the scope or enclosure created inside the functions
- Block scope
- This is the scope or enclosure created inside curly brackets
Let’s see how this looks like in examples.
- Everything outside of the function localScope is in the global scope. It is the default scope that is the parent of all local scopes.
- We also have a local scope created or enclosed by function localScope.
As we can see above all the global variables e and global can be accessed from inside the local scope as well as from the global scope. However the variables that are only found inside the local scope which are variables y and x can only be accessed from inside the local scope only. When we tried to access it from the global scope we get uncaught Reference error.
- So in short we can access variables from inside the scope they are written in but not from the outside of the scope.
What if the scope is nested inside another scope? Well, the same principle applies. The variables inside the nested scope will only be accessed by codes inside that scope. But as explained above if your code is inside the nested scope, it has access to the variables inside the scope it is in as well as all the variables outside in the subsequent chain of scope. Let’s look at the following example:-
This is put simply the accessibility of variables from the outer scope.
[Not Really! "Lexical scope is the region of text where a particular lexeme (name) has a particular meaning." In other words the scope any variable is determined by its location in the code. Look at the correction below in the comment section further explanation]
In other words it’s being able to access the variables in the parent scope and subsequent scope chain in nested functions. This is particularly important when it comes to a unique feature of functions called closure
[Not really! closure is not a feature of functions rather lexical scope. It makes it possible for function to have access to a "private" data written outside the outer environment of function. Look at the the comments below for more some more explanation for now].
But that’s a topic for another day. But here is an example of lexical scope.
This is the scope created when we use curly brackets most commonly in if/else statements, switch statements, for-loops and while loops. One interesting aspect of block scopes is that the variables inside of it can be accessed from outside the scope if they are declared using var instead of let and/or const. So you have to use let and/or const for block scope to work. Let's look at the following example:-
As you can see above block scope doesn't work with var. The variable music was accessible from outside the block scope but the variables declared with let and const were not accessible from outside the block scope. This shows that block scope only works when you declare the variables with let and/or const. What is the difference between let and const though?
Well, as the name suggests variables declared with const are constant variables. This means you only declare the variable once but also you must assign it a value. Using const can be beneficial in preventing accidental mutations of the variables. On the other hand you don't have to initialize the variable when you declare it using let. And you can assign value to the variable multiple times once it has been declared. This opens up more opportunities for accidental mutations of the variables.