Learn JavaScript in Construct, part 5: Functions

20

Index

Stats

6,547 visits, 18,233 views

Tools

Translations

This tutorial hasn't been translated.

License

This tutorial is licensed under CC BY-NC 4.0. Please refer to the license text if you wish to reuse, share or remix the content contained within this tutorial.

Scope

It's time to cover another aspect of variables: scope. This refers to where in your JavaScript code you can refer to a variable. It depends on where the variable is declared.

The logNumbers function can be adjusted to use a variable inside the function for the message:

function logNumbers(firstNumber, secondNumber)
{
	let message = `The first number is ${firstNumber} and the second number is ${secondNumber}`;
	console.log(message);
}

The variable message is scoped to the function logNumbers. In other words, it can only be used inside that function. It cannot be used outside that function, as it's outside its scope - it effectively does not exist anywhere else.

One way to demonstrate this is to try and access message anyway outside the function. Notice how the error states that message is not defined.

function logNumbers(firstNumber, secondNumber)
{
	let message = `The first number is ${firstNumber} and the second number is ${secondNumber}`;
	console.log(message);
}

// ReferenceError: message is not defined
console.log(message);

The same applies to the function parameters firstNumber and secondNumber: they are only accessible within the function body.

The same also applies to variables declared within 'if' statements and 'while' and 'for' loops. Basically anywhere you see the braces { and }, any variables declared inside there are only accessible inside that range, since the braces define a new scope.

Scope in loops

One small exception to this is a variable declared as part of a 'for' loop is also accessible both inside for (...) as well as between the braces, but not anywhere outside of that:

// 'i' cannot be used here

// 'i' can be used inside for (...)
for (let i = 0; i < 10; i++)
{
	// 'i' can be used here
}

// 'i' cannot be used here

This gives the variable a reduced scope compared to an equivalent 'while' loop:

// 'i' cannot be used here (prior to its declaration)

let i = 0;

// 'i' can be used here

while (i < 10)
{
	// 'i' can be used here
	i++
}

// 'i' can be used here

This is actually a useful aspect of 'for' loops, as it ensures the loop variable is unique to the loop.

Inner scope

While variables cannot be used outside their scope, they can be used anywhere inside their scope. One way to demonstrate this is that functions can refer to variables declared outside the function.

let message = "Hello world!";

function logMessage()
{
	// OK: 'message' is still in scope
	console.log(message);
}

logMessage();

A variable is still in scope inside any nested braces within its own scope. It's only trying to access a variable outside its scope that causes an error.

Top-level scope

A variable declared at the "top level" of a script file, i.e. not inside any braces, as with message in the previous example, is scoped to that entire file. If you add another script file, the variable won't be accessible there as other files are outside the scope of a top-level variable.

Note that top-level scope can work differently in other JavaScript environments. Construct uses modern "module" scripts, where top-level scope works this way. However if other tools or environments use the older "classic" scripts, top-level scope is actually global scope, and so top-level variables can be used across different files. Despite the fact this does not happen in Construct, it's still common in the rest of the industry, so it's worth being aware that this can work differently elsewhere.

Functions have scope too

Functions are also scoped to the place they are declared. Again referring to the previous example, the logMessage function is declared at the top level, and so can be used anywhere inside that script file, but not in other script files.

To demonstrate the scope of functions, try this code sample:

function logMessageOuter()
{
	function logMessageInner()
	{
		console.log("Hello world!");
	}
	
	logMessageInner();
}

// 'logMessageInner' is not accessible here

logMessageOuter();

This declares a nested function, or a function inside another function. logMessageInner can only be used in the function logMessageOuter and not outside of it. The function is scoped the same way as a variable declared inside logMessageOuter.

Summary

Scope is an important aspect of variable declarations, function declarations and function parameters, which defines where they can be used. In short, each pair of braces { and } defines a new scope, and anything not inside any braces is at the top level. Something declared in a particular scope can be used anywhere inside that scope, including inner scopes, but not outside of that scope. Scope becomes an important feature when dealing with functions, which is why we took a little detour to cover it now.

These rules about scope help keep code organised as it prevents things being accidentally used outside of where they're meant to be used. It also generally removes the need to worry about if a name is used somewhere else in a large program, since you only need to think about what is in scope for a particular piece of code.

It is possible to use top-level functions and variables in other script files if they are explicitly placed in global scope, or exported and imported, but these are more advanced topics that we'll cover later on in this guide.

Next Tutorial In Course

Learn JavaScript in Construct, part 6: More on functions 15:10

Covers more details about functions in JavaScript, including function expressions, recursion, arrow functions and closures.

  • 2 Comments

  • Order by
Want to leave a comment? Login or Register an account!