Global Variables vs Local Variables in JavaScript- Key Differences

What the Hell Is Variable Scope in JavaScript?

Before you can understand the difference between global and local variables, you need to wrap your head around scope. Scope is simply the part of your code where a variable is accessible. That's it. Nothing fancy.

JavaScript has three types of scope:

Variables declared with var are function-scoped. Variables declared with let and const are block-scoped. This distinction matters more than most tutorials admit.

Global Variables: When Your Data Lives Everywhere

A global variable is declared outside any function. You can access it from anywhere in your code — inside functions, loops, conditionals, other files (if properly exported).

How to Create a Global Variable

Three ways to do this:

// Method 1: Declare outside any function
const appName = "MyApp";
let version = 1.0;

// Method 2: Assign to window object (bad practice, but it works)
window.apiKey = "12345";

// Method 3: Omit let/const/var in non-strict mode (really bad practice)
globalVar = "I exist everywhere";

Method 3 will bite you. In strict mode, it throws an error. In sloppy mode, it creates an accidental global. Don't do it.

When Global Variables Make Sense

Honestly? Rarely. But there are legitimate use cases:

The Problem with Global Variables

Global variables create tight coupling. Any function can modify them. Any part of your code can overwrite them. Debugging becomes a nightmare because changes can come from anywhere.

Imagine fifty functions all reading and writing to the same global variable. Which one broke it? Good luck finding out.

Local Variables: Keeping Your Data Contained

A local variable is declared inside a function or block. It only exists within that scope and disappears when the function/block finishes executing.

Function-Scoped Local Variables (var)

function calculateTotal(price, quantity) {
    var discount = 0.1; // local to this function
    var subtotal = price * quantity;
    var total = subtotal - (subtotal * discount);
    return total;
}

console.log(discount); // undefined - discount doesn't exist here

Block-Scoped Local Variables (let and const)

function processUser(user) {
    if (user.isActive) {
        let status = "active"; // only exists inside this if block
        const message = "User is online";
        console.log(message, status);
    }
    
    console.log(status); // ReferenceError - status doesn't exist here
}

The difference between var and let/const is huge. var leaks out of blocks. let and const stay locked in.

Global vs Local Variables: The Key Differences

Here's what separates them:

Aspect Global Variables Local Variables
Declaration Outside all functions Inside functions or blocks
Accessibility Everywhere in the code Only within declaring scope
Lifetime Until page/script closes Until function/block ends
Memory Occupies memory longer Freed after use
Risk Name collisions, unexpected changes Contained, predictable
Testing Harder to test in isolation Easier to test

Scope Chain: How JavaScript Finds Variables

When JavaScript encounters a variable, it searches in this order:

  1. Current scope — is the variable declared here?
  2. Parent scope — is it declared in the enclosing function?
  3. Grandparent scope — keep going up the chain
  4. Global scope — last resort
  5. ReferenceError — variable doesn't exist anywhere
const globalVar = "I'm global";

function outer() {
    const outerVar = "I'm in outer";
    
    function inner() {
        const innerVar = "I'm in inner";
        console.log(globalVar); // Found at global scope
        console.log(outerVar);  // Found at outer scope
        console.log(innerVar);  // Found at current scope
    }
    
    console.log(innerVar); // ReferenceError - innerVar is local to inner()
}

Common Mistakes That Will Ruin Your Code

Mistake #1: Accidental Globals

function badExample() {
    result = 10; // Oops - no var/let/const
    // This creates a global variable!
}

badExample();
console.log(result); // 10 - result is now global

Always declare your variables. Always.

Mistake #2: Shadowing

let count = 0; // global

function increment() {
    let count = 10; // This is a NEW local variable, not the global one
    count++;
    console.log(count); // 11
}

increment();
console.log(count); // 0 - global count is unchanged

The local count shadows the global count. They are completely separate variables.

Mistake #3: Relying on Hoisting

function broken() {
    console.log(value); // undefined (hoisted but not assigned)
    var value = 100;
    console.log(value); // 100
}

var declarations get hoisted to the top of their function. The variable exists, but it has no value yet. This causes bugs that are hard to track down.

Practical How-To: Choosing the Right Variable Type

Here's a decision tree you can actually use:

Modern Module Pattern Example

// Instead of polluting global scope:
const AppState = (function() {
    // Private variables - truly local
    let count = 0;
    let users = [];
    
    // Public API
    return {
        increment: () => count++,
        getCount: () => count,
        addUser: (user) => users.push(user),
        getUsers: () => [...users] // return copy, not reference
    };
})();

AppState.increment();
console.log(AppState.getCount()); // 1
console.log(count); // ReferenceError - count is private

This pattern keeps variables local to an IIFE while exposing only what you need. No globals, clean API.

ES6+ Best Practices

If you're writing JavaScript in 2024 and still using var for everything, stop. Here's what you should do:

// Modern approach - no globals needed
// file: config.js
export const API_URL = "https://api.example.com";
export const TIMEOUT = 5000;

// file: app.js
import { API_URL, TIMEOUT } from './config.js';

fetch(API_URL, { timeout: TIMEOUT });

Modules give you encapsulation without globals. Use them.

Quick Reference

Keyword Scope Hoisting Reassignment
var Function Declaration hoisted, value is not Allowed
let Block Temporal dead zone (can't access before declaration) Allowed
const Block Temporal dead zone Not allowed (but object properties can change)

The Bottom Line

Global variables are not evil, but they're overused by beginners who don't understand scope. Local variables keep your code predictable and testable. The rule is simple: declare variables with the smallest scope possible. If you need data in multiple places, pass it as a parameter or use ES6 modules.

Most bugs I see in JavaScript code come from too many globals and var keyword confusion. Fix those two things and your code quality improves immediately.