JavaScript Function Scope Local vs Global Scope
Local scope keeps variables inside functions. Global scope makes them visible everywhere. Learn where each variable lives, why it matters, and how to avoid accidental global pollution.
Scope is the rule that determines where a variable is visible and where it is not. If you declare a variable inside a function, code outside that function cannot see it. If you declare it outside any function, every function can see it. That is the core difference between local and global scope.
const globalMessage = "I am visible everywhere";
function showMessage() {
const localMessage = "I am only visible inside this function";
console.log(globalMessage); // Works: global is visible here
console.log(localMessage); // Works: local is in scope
}
showMessage();
console.log(globalMessage); // Works
console.log(localMessage); // ReferenceError: localMessage is not definedglobalMessage is declared in the top-level scope. Every function can access it. localMessage is declared inside showMessage. Only code inside that function can see it.
How Scope Nesting Works
Scope in JavaScript is hierarchical. Inner scopes can see outer scopes, but outer scopes cannot see inner scopes:
Think of it like one-way glass. Code inside a function can look out and see global variables. Code outside cannot look in and see function variables.
const outer = "I am outside";
function middle() {
const inner = "I am inside middle";
function deepest() {
console.log(outer); // Works: looking outward through the scope chain
console.log(inner); // Works: looking one level up
}
deepest();
}Calling middle triggers deepest, which can see both its own parent's variable and the outer global one. But the reverse is not possible, code outside deepest has no way to reach into it:
middle();
console.log(outer); // Works
// console.log(deepestVar) would fail -- cannot look into deepestGlobal Scope
A variable has global scope when it is declared outside any function or block. In browsers, global variables become properties of the window object. In Node.js, they are properties of the global object.
// Global scope -- visible everywhere
const API_URL = "https://api.example.com";
let currentUser = null;
function login(user) {
currentUser = user; // Accessing global variable
}
function getApiUrl() {
return API_URL; // Accessing global constant
}Global constants like API_URL are generally fine. Global mutable state like currentUser is risky, any function can change it, making bugs hard to trace.
Local (Function) Scope
Every function creates its own local scope. Parameters and variables declared inside the function belong to that scope:
function calculateTotal(price, quantity) {
// price and quantity are local (parameters)
const tax = 0.08; // local variable
const total = price * quantity * (1 + tax); // local variable
return total;
}
console.log(tax); // ReferenceError: tax is not definedParameters count as local variables. They exist only for the duration of the function call, and once the function returns, that entire local scope, tax included, is gone and unreachable from anywhere else.
var vs let vs const in Scope
var is function-scoped. let and const are block-scoped. This difference matters inside blocks like if statements and loops:
function testVar() {
if (true) {
var x = "var is function-scoped";
}
console.log(x); // "var is function-scoped" -- still visible!
}
function testLet() {
if (true) {
let y = "let is block-scoped";
}
console.log(y); // ReferenceError: y is not defined
}With var, the variable leaks out of the if block because var only cares about function boundaries. With let and const, the curly braces create a hard boundary.
| var | let / const | |
|---|---|---|
| Scope boundary | Nearest function | Nearest block ({}) |
| Visible outside an if or loop block | Yes | No |
| Typical result | Accidental leakage | Contained, predictable |
This is why let and const are preferred. They scope variables to the smallest reasonable container, reducing accidental leakage. For more, see JavaScript Variable Naming Conventions Rules.
The Problem with Too Many Globals
Global variables create risks that grow with the size of the codebase, since every additional file that can read or write a global is another place a bug could originate from:
- Naming collisions: two scripts use the same variable name and overwrite each other.
- Accidental mutation: any function can change any global, making bugs hard to trace.
- Testability: global state must be set up and torn down between tests.
- Readability: you cannot tell where a global variable is modified just by reading one function.
// Risky: global mutable state
let cart = [];
function addToCart(item) {
cart.push(item); // Any function could also modify cart
}
function clearCart() {
cart = []; // Another global mutation
}A better approach is to pass state explicitly or use closures, so the data lives inside a function scope instead of sitting in the global namespace where anything can reach it:
function createCart() {
const items = []; // Private, not global
return {
add(item) { items.push(item); },
getAll() { return [...items]; },
clear() { items.length = 0; },
};
}
const cart = createCart();
cart.add("Book");
console.log(cart.getAll()); // ["Book"]The items array is completely private. No other code can touch it. For more on this pattern, see Returning Functions from Functions in JavaScript.
Rune AI
Key Insights
- Local scope: variables declared inside a function are only visible inside that function.
- Global scope: variables declared outside any function are visible everywhere.
- var is function-scoped. let and const are block-scoped.
- Functions can see variables from their outer scopes, but outer scopes cannot see into functions.
- Keep variables as local as possible to avoid naming collisions and accidental mutations.
Frequently Asked Questions
Should I ever use global variables?
What is the difference between function scope and block scope?
Do modules have their own scope?
Conclusion
Scope is the set of rules that determines where a variable is visible. Local scope keeps variables contained inside functions or blocks. Global scope makes them visible everywhere. The key skill is knowing where your variables live and keeping them as local as possible to avoid conflicts, bugs, and maintenance headaches.
More in this topic
JavaScript While Loop Explained: A Complete Guide
A while loop repeats code as long as a condition stays true. Learn the syntax, see practical examples, and understand when a while loop is the right choice over a for loop.
JavaScript Loops Tutorial: for, while, do while
Loops let JavaScript repeat code without writing it twice. Learn the three core loop types, what each one does, and when to choose one over another.
How to Loop Through Arrays Using JS for Loops Guide
Looping through arrays is the most practical use of JavaScript for loops. Learn how to access each element by index, avoid off-by-one errors, and choose between for, for...of, and forEach.