Uni-Sine
Computer ScienceProgramming and algorithms

Functions and variable scope: local and global variables

Variable scope is the part of a program where a variable can be used. A variable declared inside a function is local: it exists only while that function runs, and only that function can see it. A variable declared outside every function is global, and any part of the program can read and change it.

The examples below are in JavaScript, and you can paste any of them into the Code Editor and run it. The ideas are the same in Python, pseudocode and most other languages.

What is a function?

A function is a named block of code that does one job. You write it once and call it by name whenever you need that job done, which keeps programs shorter and easier to test. Exam boards call functions and procedures subroutines: the AQA GCSE specification describes a subroutine as a named "out of line" block of code that can be called.

function area(width, height) {
  return width * height;
}

console.log(area(4, 7));   // 28

Parameters and arguments

width and height are parameters: names in the definition that stand for the inputs. The values in the call, 4 and 7, are arguments. They are matched to the parameters in order, so width becomes 4 and height becomes 7.

Return values, functions and procedures

return ends the function and sends a value back to the line that called it, so area(4, 7) is replaced by 28. In GCSE terms, a subroutine that returns a value is a function, and one that just does something, such as printing, without returning a value is a procedure. JavaScript and Python use the word function for both.

Try it: put the lines of this function in order so it returns the target text, then press Mark to check your answer in the course.

Drag code snippets into the function to produce the target output.

Press Mark to have your answer marked in the HTML, CSS & JavaScript course.

What is variable scope?

Scope answers one question: from this line, which variables can I see? MDN defines it as the context in which values and expressions are visible. There are three levels to know.

ScopeDeclaredCan be usedExists until
GlobalOutside every functionAnywhere in the programThe program ends
Local (function)Inside a function, including its parametersOnly inside that functionThe function returns
BlockWith let or const inside { }, such as a loop or ifOnly inside those bracesThe block finishes

Local and global variables

let total = 0;                 // global

function addScore(points) {
  let bonus = 5;               // local
  total = total + points + bonus;
  return total;
}

console.log(addScore(10));     // 15
console.log(addScore(3));      // 23
console.log(bonus);            // ReferenceError: bonus is not defined

total is global, so addScore can change it and the change is still there on the next call. bonus and the parameter points are local. They are created fresh on every call and thrown away when the function returns, which is why the last line fails.

Shadowing: the same name inside and outside

If a function declares a local variable with the same name as a global one, the local one wins inside the function. This is called shadowing. The global variable is untouched.

let count = 1;

function reset() {
  let count = 99;   // a new local count
  return count;
}

console.log(reset(), count);   // 99 1

Block scope: let, const and var

In JavaScript, let and const are block scoped: a variable declared inside a loop or an if statement disappears at the closing brace. The older var ignores blocks and is scoped to the whole function, or made global if it is outside any function. That is one reason modern code avoids var.

for (var i = 0; i < 3; i++) {}
console.log(i);   // 3: var leaks out of the loop

for (let j = 0; j < 3; j++) {}
console.log(j);   // ReferenceError: j is not defined

Nested functions

A function written inside another function can see its own variables, the outer function's variables and the globals. It looks outwards, one level at a time, until it finds the name. It can never look inwards.

let a = "global";

function outer() {
  let b = "outer";
  function inner() {
    let c = "inner";
    return a + " " + b + " " + c;
  }
  return inner();
}

console.log(outer());   // global outer inner

Here inner can use a, b and c. outer can use a and b but not c, and code outside both can use only a.

Try it

Code Editor

Write and run code right in your browser

Go to its page

The call stack

The call stack is how the computer keeps track of which function is running. Each call pushes a stack frame holding that call's parameters, local variables and the place to return to. When the function returns, its frame is popped off and its local variables go with it. The last function called is the first to finish, so the stack is last in, first out (LIFO).

When outer() runs above, the stack grows like this:

  1. The main program calls outer: its frame, holding b, goes on the stack.
  2. outer calls inner: a frame holding c goes on top.
  3. inner returns its text: its frame is popped and c is gone.
  4. outer returns: its frame is popped and b is gone. Only the global a is left.

Recursion and the base case

A recursive function calls itself on a smaller version of the problem. It needs a base case, a condition where it stops calling itself, or the calls never end.

function sumTo(n) {
  if (n === 1) return 1;     // base case
  return n + sumTo(n - 1);   // recursive case
}

console.log(sumTo(4));   // 10

sumTo(4) needs sumTo(3), which needs sumTo(2), which needs sumTo(1). That is four frames on the stack at once. The base case returns 1, then each frame adds its own n on the way back: 1 + 2 + 3 + 4 = 10. Without the base case the stack fills up and the program crashes, which JavaScript in Chrome reports as "RangeError: Maximum call stack size exceeded".

Higher-order functions and callbacks

In JavaScript a function is a value, like a number or a string, so you can pass it into another function. A function that takes or returns a function is a higher-order function, and a function passed in is a callback.

const addThree = (n) => n + 3;

function twice(f, x) {
  return f(f(x));
}

console.log(twice(addThree, 10));   // 16

twice calls the callback on 10 to get 13, then on 13 to get 16. Array methods such as map and filter, and event handlers on web pages, all work this way. The Programming Languages course covers the functional style this leads to, and how the stack and heap manage memory.

Common mistakes

  • Using a local variable outside its function. It no longer exists once the function returns. Return the value instead.
  • Mixing up parameters and arguments. Parameters are the names in the definition; arguments are the values in the call.
  • Forgetting to return. A function with no return gives back undefined in JavaScript and None in Python.
  • Changing globals from inside functions. It works, but any function could be the one that changed it, so bugs are hard to find. Pass values in as parameters and return results.
  • Recursion with no base case, or a recursive call that never gets closer to it.

Common questions

What is scope in programming?
Scope is the region of a program where a variable or function name can be used. A variable declared inside a function has local scope and can only be used there. One declared outside all functions has global scope and can be used anywhere.
What is the difference between a local and a global variable?
A local variable is declared inside a subroutine, exists only while it runs and can only be used inside it. A global variable is declared outside all subroutines, lasts for the whole program and can be read or changed from anywhere.
Why should you avoid global variables?
Any part of the program can change a global variable, so when its value is wrong it is hard to find out which code changed it. Functions that use globals also depend on code outside them, which makes them harder to test and reuse.
What is the difference between a function and a procedure?
In GCSE Computer Science, a function returns a value to the code that called it, and a procedure carries out a task without returning a value. Both are types of subroutine. Many languages, including Python and JavaScript, call both functions.
Is var function scoped in JavaScript?
Yes. A variable declared with var belongs to the whole function it is in, or is global if it is outside every function. Variables declared with let and const are block scoped, so they only exist inside the nearest pair of braces.
What is a stack overflow?
It happens when too many function calls are waiting on the call stack at once, usually because a recursive function has no base case or never reaches it. The stack runs out of room and the program stops with an error.

Revision cards

Say the answer first, then flip the card to check it.

Where to go next

  • Solve it

    Code Editor

    Write and run code right in your browser

    Open the tool
  • Learn it

    HTML, CSS & JavaScript

    Learn how to think like a web developer from the ground up

    Start the course
  • Test it

    GCSE Computer Science

    A new exam-style paper every day, with instant marking and a mark scheme

    Start today's paper
Read next
Computer Science · Programming and algorithmsConditional statements in programming: if, else and logicHow conditional statements in programming work: if, elif and else, comparison operators, AND, OR and NOT, truth tables, with Python and JavaScript code.