Variable Scope and Shadowing in JavaScript Functions
Variable scope determines the accessibility of variables throughout different parts of a script. In JavaScript, variables are typically categorized into global and local scopes, which dictate how values are read or updated within and outside functions.
Global and Function Scope
A variable declared outside any function resides in the global scope. It is accessible from any part of the code, including inside functions. Conversely, variables declared with var, let, or const inside a function are local to that function and cannot be accessed from the outer scope.
var sharedValue = 25;
function modifyScope() {
var secretValue = 500;
console.log(sharedValue); // Outputs: 25
sharedValue = 100; // Updates the global variable
}
modifyScope();
console.log(sharedValue); // Outputs: 100
// console.log(secretValue); // Throws ReferenceError: secretValue is not defined
In this example, sharedValue is a global variable. When updated inside modifyScope, the change persists globally. However, secretValue is restricted to the function's internal environment.
Variable Shadowing and Hoisting
If a local variable is declared with the same name as a global variable, the local version shadows the global one within that function's scope. When using var, the declaration is hoisted to the top of the function, which can lead to unexpected undefined results if accessed before the assignment.
var status = "active";
function checkStatus() {
console.log(status); // Outputs: undefined (hoisted local declaration)
var status = "inactive";
console.log(status); // Outputs: "inactive"
}
checkStatus();
console.log(status); // Outputs: "active"
Inside checkStatus, the local status variable takes precedence over the global one. Because of hoisting, the JavaScript engine recognizes that a local status exists throughout the function, but it remains uninitialized until the line where it is assigned.
Function Parameters as Local Scope
Function parameters act as local variables. When a value is passed into a function, it is assigned to the parameter name within the local scope. If the parameter name matches a global variable name, operations performed on the parameter do not affect the global variable (for primitive types).
var points = 10;
function calculatePoints(points) {
points = points + 90;
console.log("Local points:", points); // Outputs: 100
return points;
}
calculatePoints(points);
console.log("Global points:", points); // Outputs: 10
In this scenario, points inside the function is a distinct local reference. Modifying it does not overwrite the global points variable because primitive values (like numbers and strings) are passed by value. If the variable were an object or an array, modifying its properties would affect the original global object due to reference-based passing.