Exercise
Scope in JavaScript refers to the current context of execution — it determines the accessibility (visibility) of variables, functions, and objects in some particular part of your code during runtime.
JavaScript has three main types of scope: Global Scope, Function Scope, and Block Scope. ES6 introduced block scope with let and const.
A variable declared in the global scope is accessible from anywhere in the JavaScript program. Variables declared outside of any function or block exist in the global scope.
var globalVar = 'I am global';
function greet() {
console.log(globalVar); // accessible here
}
greet(); // Output: I am global
Variables declared inside a function are only accessible within that function. This is called function scope. Attempting to access them outside the function will throw a ReferenceError.
function myFunction() {
var localVar = 'I am local';
console.log(localVar); // Output: I am local
}
myFunction();
console.log(localVar); // ReferenceError: localVar is not defined
Block scope means a variable is only accessible within the block (curly braces { }) in which it is declared. let and const are block-scoped, while var is not.
{
let blockVar = 'I am block scoped';
console.log(blockVar); // Output: I am block scoped
}
console.log(blockVar); // ReferenceError: blockVar is not defined
var is function-scoped and is accessible throughout the entire function it is declared in. let and const are block-scoped and are only accessible within the block they are declared in.
function scopeDemo() {
if (true) {
var x = 'var'; // function-scoped
let y = 'let'; // block-scoped
const z = 'const'; // block-scoped
}
console.log(x); // Output: var
console.log(y); // ReferenceError
console.log(z); // ReferenceError
}
Lexical scope means that the scope of a variable is determined by its location in the source code at the time it is written, not at run time. An inner function has access to variables in its outer (parent) function.
function outer() {
var outerVar = 'I am outer';
function inner() {
console.log(outerVar); // inner can access outer's variable
}
inner(); // Output: I am outer
}
outer();
The scope chain is the mechanism JavaScript uses to look up variables. When a variable is referenced, JavaScript first looks in the current scope. If not found, it moves up to the parent scope, continuing until it reaches the global scope or throws a ReferenceError.
var globalVar = 'global';
function outer() {
var outerVar = 'outer';
function inner() {
var innerVar = 'inner';
console.log(innerVar); // found in inner scope
console.log(outerVar); // found in outer scope
console.log(globalVar); // found in global scope
}
inner();
}
outer();
Hoisting is JavaScript's default behavior of moving variable and function declarations to the top of their scope before code is executed. Only declarations are hoisted, not initializations.
console.log(myVar); // Output: undefined (not a ReferenceError)
var myVar = 'hello';
// The above is interpreted as:
// var myVar;
// console.log(myVar);
// myVar = 'hello';
Yes. In JavaScript, inner scopes can access variables from their outer (enclosing) scopes, but outer scopes cannot access variables defined inside inner scopes. This is the basis of lexical scoping.
var outerVar = 'outer';
function innerFunction() {
// inner can access outer variable
console.log(outerVar); // Output: outer
}
innerFunction();
// outer cannot access inner variable
function anotherFunction() {
var innerOnly = 'inner only';
}
console.log(innerOnly); // ReferenceError