Local and Global Variables (Scope)

Think about the word "home". In your house, "home" means your house. In your friend's house, "home" means their house. Same word, but what it points to depends on where you are. Variables in a program work the same way: where a variable is created decides where it can be seen and used. That reach — the region of the program where a variable exists — is called its scope.

There are two scopes you need to know for GCSE:

This builds directly on : now that you can write named blocks of code, the big new question is which variables can each block actually see?

A local variable lives and dies inside its subroutine

When you declare a variable inside a subroutine, it is created fresh each time the subroutine runs, and it is thrown away when the subroutine ends. Inside, you can use it freely. Run this:

function greetPupil(): void { const name = "Ada"; // 'name' is LOCAL to greetPupil console.log("Welcome, " + name + "!"); } greetPupil(); console.log("Done greeting.");

Inside greetPupil the variable name works perfectly. But it is trapped inside that subroutine — the rest of the program has no idea it ever existed. If we tried to print name after the call, the program would refuse to run, because out there name is out of scope:

function greetPupil(): void { const name = "Ada"; // 'name' only exists in here console.log("Welcome, " + name + "!"); } greetPupil(); console.log(name); // ERROR: 'name' is not defined out here — it's out of scope

This is a good thing, not a nuisance. The local variable is a private workspace: nothing outside can touch it, and it doesn't clutter up the rest of the program.

Two subroutines, each with its own local — no clash

Because a local variable belongs only to its own subroutine, two different subroutines can each have a variable with the same name and they will not interfere. Each keeps its own private copy. Here both tickets and coats use a local called count, and they count completely independently:

function countTickets(): void { let count = 0; // this 'count' is local to countTickets count = count + 3; console.log("Tickets sold:", count); } function countCoats(): void { let count = 0; // a DIFFERENT 'count', local to countCoats count = count + 10; console.log("Coats stored:", count); } countTickets(); countCoats(); countTickets(); // starts fresh at 0 again — its count did not remember 3

Notice the third call to countTickets prints 3 again, not 6. Its local count is created anew each time the subroutine starts and destroyed when it ends. And countCoats's count is an entirely separate box that happens to share the name. Two programmers could write these two subroutines without ever talking to each other, and their code would still work side by side. That self-contained-ness is exactly why locals are usually the right choice.

A global variable is visible everywhere

A variable declared outside every subroutine is global. Any subroutine can read it and change it. Sometimes that is genuinely useful — for a setting or a running total that the whole program shares:

let score = 0; // GLOBAL: declared outside all subroutines function addPoints(): void { score = score + 5; // this subroutine can see and change the global } function showScore(): void { console.log("Score is now:", score); // and so can this one } addPoints(); addPoints(); showScore(); // both subroutines shared the SAME 'score'

Here score survives between calls and is shared by both subroutines — the opposite of a local. That sharing is the point of a global, but it is also its danger, as we'll see.

Why locals are usually the better choice

For your exam, remember these reasons that local variables are normally preferred:

Because some data really is shared by the whole program and needs to outlive any single subroutine — a high score, the current difficulty setting, whether dark mode is on. A global is the honest tool for something that is genuinely program-wide. The rule of thumb professionals use is: make everything local by default, and only reach for a global when a value is truly shared across the whole program. If in doubt, keep it local and pass it in and out instead.

1. You cannot use a local variable outside its subroutine. Once the subroutine ends, its locals are gone. Reaching for one from outside is an "out of scope" error — the name simply isn't defined there:

function loadLevel(): void { const enemies = 12; // local to loadLevel } loadLevel(); console.log(enemies); // ERROR: 'enemies' is out of scope here

2. Over-using globals leads to sneaky bugs. When many subroutines can all change the same global, some far-away piece of code can alter a value while you weren't looking, and a completely different part of the program breaks. Here two subroutines both write to the global total, and it becomes very hard to be sure what its value is at any moment:

let total = 100; function applyDiscount(): void { total = total - 30; } function addDelivery(): void { total = total + 50; } // Somewhere far away, in a big program, who changed 'total' — and when? // With a global, the answer could be ANY subroutine. That is the bug trap.

The habit to build: declare a variable in the smallest scope that still works. If only one subroutine needs it, make it local there. Save globals for the rare value the whole program genuinely shares.