Part 5: What is Variable Scope in Javascript?
This is Part 5 of my I Need To Learn More JavaScript series.
- Part 1: What is a Closure in JavaScript?
- Part 2: What is forEach and Map in JavaScript?
- Part 3: What is a Reference in JavaScript?
- Part 4: What is Event Delegation in JavaScript?
- Part 5: What is Variable Scope in JavaScript?
What is a variable’s scope?
A variable’s scope is the level at which the variable can be accessed.
In other words, scope determines the accessibility of a variable from other parts of your code. Where can I access this variable? That is determined by the variable’s scope.
What are the types of scope?
There are 2 basic types of scope in Javascript, Global and Local Scope.
Global Scope
A variable is said to be globally scoped if it is visible from all other scopes.
A Global Scope Example:
The 3 variables mickeyMouse, age, and creator are accessible everywhere. Even inside of functions. Therefore they are globally scoped. Anywhere in my application I can access these variables.
Local Scope
Variables that are declared inside of a function are locally bound to that function. Every function has its own scope, and variables declared in a function are “locally scoped” to that function.
A Locally Scoped Example:
Notice here the variables, themeParkLocation, question, and response are NOT accessible everywhere.
If I try to access these locally scoped variables from the elsewhere in my application (line 16), I get a ReferenceError — undefined.
Therefore, these variables are said to be locally scoped — locally scoped to the function whatIsDisneyland(). They are NOT accessible elsewhere in my application.
What about Block Scope? — ES6 only
A block scoped variable is a variable that is only accessible within a block.
For more on blocks read the docs!
In ES6, ONLY the keywords const and let allow developers to declare variables within the block scope. You cannot declare a variable with var
and have it be blocked scope. Let’s look at an example below!
A Block Scope Example:
The variable functionScopeVariable
is declared with a var
inside of a block
Since var
variable’s can’t be blocked scope, the variable functionScopeVariable
is accessible ALSO OUTSIDE of the block where it was declared (as seen in line 17).
However, the variables declared with let
and const
are block scoped and are NOT accessible outside of the block where they were declared (line 18). When I try to access them outside of the block, I receive an error!
As stated above, variables declared with var
cannot be blocked scoped. If you declare a variable with var
inside a block, the variable is “hoisted” to the nearest enclosing function. In the example above, the nearest enclosing function is the function blockScope()
.
Variables declared with
var
in a block are hoisted to the nearest enclosing function.
Therefore, the variable functionScopeVariable
is locally scoped (to the blockScope() function), despite the variable being declared inside a block.
Here is another example:
Above the variable, globallyScoped
is declared within a block with var
. Stated again, variables declared with var
in a block are hoisted to the nearest enclosing function. Since there is no enclosing function, the variable, globallyScoped
is hoisted to the global scope.
A variable declared with var in a block with no enclosing function is hoisted into the global scope.
This annoying fact of pre ES6 JavaScript was one of the major drivers of creating const
and let
. Prior to the release of ES6, if you declared a variable with var
in a block , the variable would “leak out” and potentially the global namespace.
A Side Note — Lexical Scope
“Lexical Scoping defines how variable names are resolved in nested functions: inner functions contain the scope of parent functions even if the parent function has returned.”
Lexical scope means that the children or nested scopes has access to variables defined in the parent scope. In other words, nested functions have access to variables declared in their outer scope.
A Lexical Scope Example:
Here inside the inner function has access to the variable declared in the parent scope. This is lexical scoping.
Why does Lexical Scoping Matter?
The lexical environment of JavaScript allows you to create closures. A closure is when a function is able to remember and access its lexical scope even when that function is executing outside its lexical scope.
Or simply stated, a closure is an inner function that has access to the outer function’s variables, even if that outer function has returned.
A closure example:
var outerNumber = 30function outer() {
var innerNumber = 20
function inner() {
return outerNumber + innerNumber
}
return inner()
}outer() //prints 50
Closures are important because they ensure data privacy and are a great way to more less create private variables
.
For more information on closures please read my blog post!
Scoping in a Nutshell
There are two types of scopes: Global and Local.
A variable is said to be “globally scoped” if it accessible from all other scopes.
Variables that are declared inside of a function are said to be “locally scoped to that function.”
A block scoped variable is declared within a block with the ONLY the keywords let or const.
Lexical Scoping allows nested functions have access to variables declared in their outer scope.