Scope in JavaScript refers to the current context of code, which determines the accessibility of variables to JavaScript. The concept of scope is pivotal for understanding how variables and functions are declared, accessed, and modified in JavaScript. Scope can be broadly categorized into two types: lexical scope (also known as static scope) and dynamic scope. However, JavaScript primarily uses lexical scoping, where the scope of a variable is defined by its location within the source code.
Types of Scope
There are several types of scope in JavaScript:
-
Global Scope: A variable declared outside of any function or block has a global scope, meaning it can be accessed and modified from any part of the code.
-
Function Scope: Variables declared within a function are scoped to that function, making them accessible only within that function. This is specific to variables declared with
var
or function declarations. -
Block Scope: Introduced in ES6 with the
let
andconst
keywords, block scoping means that a variable declared inside a block{}
is only accessible within that block. This applies to loops, conditionals, and any code block.
Lexical Scoping
JavaScript uses lexical scoping, which means the scope of a variable is determined by the structure of the program code (the location of the variable declaration within the source code). Nested functions have access to variables declared in their outer scope.
function outerFunction() {
let outerVar = 'I am outside!';
function innerFunction() {
console.log(outerVar); // Can access outerVar
}
innerFunction();
}
outerFunction(); // Logs: 'I am outside!'
In this example, innerFunction
has access to variables in outerFunction
due to lexical scoping.
Scope Chain
The scope chain is the mechanism for resolving the value of variables in JavaScript. When code needs to access a variable, JavaScript starts looking for the variable in the current scope. If it doesn't find it there, it moves to the next outer scope, continuing this process until it finds the variable or reaches the global scope. If the variable is still not found, a ReferenceError
is thrown.
Hoisting
Hoisting is a behavior in JavaScript where variable and function declarations are moved to the top of their containing scope during the compile phase. This means that variables can be referenced before they are declared. Note that only the declarations are hoisted, not the initializations.
- Variables declared with
var
are hoisted to the top of their function or global scope. - Variables declared with
let
andconst
are also hoisted, but they remain in a "temporal dead zone" from the start of the block until the declaration is encountered. Accessing them before the declaration results in aReferenceError
.
Closure
A closure is a function that remembers the variables from the place where it is defined, regardless of where it is executed. Closures allow functions to access those variables through the scope chain even if the outer function has finished executing, maintaining scope beyond the lifetime of the outer function.