Javascript Variable Scope & Closures: A Primer

1 23KtUDuCv mOboccUiZGtg

Javascript might seem like a pretty approachable programming language to most people, however certain concepts can prove quite tricky for beginners. One of the most commonly brought-up topics is that of variable scope and what closures are, so in this artile I will try to introduce these concepts in a beginner-friendly way.

Scope

When we talk about scope, we mean the visibility of one or more entities to certain parts of our code. For the purposes of this article, our entities are going to be limited to variables.

There are two types of scope in Javascript: global and local.

Global scope is pretty straightforward: Any variable defined outside any function or curly braces is part of the global scope and can be accessed from anywhere in the code.

Local scope is slightly more complicated. Any variable defined inside a function declaration or curly braces can only be accessed inside the function or block of code it was declared respectively.

Okay, this is basically all you need to know about variable scope. Let’s look at some simple examples:

// This variable is part of the global scope
var globalVariable = 10;
function someFunction(){
// globalVariable is accessible from someFunction,
// as it is part of the global scope
console.log(globalVariable);
}
someFunction(); // Prints 10

// This is a function and it defines its own
// local scope. argumentVariable is part of the
// function's scope, as it is an argument in its
// definition.
function parentFunction(argumentVariable){
// functionVariable and anotherVariable are both
// part of parentFunction's local scope.
var functionVariable = 10;
let anotherVariable = 15;
// This is another function enclosed inside the
// first one. It also defines its own scope, but
// it has access to its parent function's scope.
function childFunction(){
// childVariable is part of childFunction's local
// scope.
var childVariable = 20;
// anotherVariable is not the same as the one
// defined in parentFunction's scope, due to it
// being defined using the keyword 'let'.
let anotherVariable = 25;
// childFunction has access to variables defined
// in parentFunction and childFunction, however
// it does contain its own definition of
// anotherVariable and has no access to parentFunction's
// anotherVariable.
console.log("Child function: ");
console.log(functionVariable);
console.log(childVariable);
console.log(anotherVariable);
}
// parentFunction does not have access to variables
// defined in childFunction, thus it cannot access
// childVariable and it can only see its definition
// of anotherVariable.
console.log("Parent function: ");
console.log(functionVariable);
console.log(anotherVariable);
childFunction();
}
parentFunction();
view raw functionScope.js hosted with ❤ by GitHub

function someFunction(){
if (true){
// This variable is defined inside these
// curly braces, which means its part of the
// scope of this block and cannot be accessed
// by other parts of someFunction.
let blockVariable = 30;
// However, using the 'var' keyword this variable,
// while defined inside the same block, is part of
// the scope of the someFunction.
var functionVariable = 30;
// Inside the block, both variables are accessible.
console.log("Block scope: ");
console.log(blockVariable);
console.log(functionVariable);
}
// Outside the block, only the variable defined using
// the keyword 'var' is accessible.
console.log("Function scope: ");
try { console.log(blockVariable); }
catch (e) { console.log("The variable 'blockVariable' is not accessible!"); }
try { console.log(functionVariable); }
catch (e) { console.log("The variable 'functionVariable' is not accessible!"); }
}
someFunction();
view raw blockScope.js hosted with ❤ by GitHub

Block scope and definitions using var and let might seem slightly confusing at first, but I recommend you read A guide to Javascript variable hoisting with let and const (3 min read) and carefully study MDN’s documentation of the [let](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let) keyword to clear up any remaining questions and doubts.

Closures

Closures are one of those things that might seem confusing at first, but really aren’t. A function defined inside another function is a closure. Closures are particularly useful when you want to access a variable defined inside a function’s scope from outside the function.

A practical use of closures could be defining a public set of functions that can get or set some private variables inside a function (which is a pretty common use-case in object-oriented programming). Here’s a pretty simple example of closures in action:

function user(username, password){
// Here we use closures to define public functions
// that can access private variables.
return {
getUsername() { return username; },
setUsername(newUsername) {username = newUsername; },
checkPassword(givenPassword) { return password == givenPassword; }
}
}
var myUser = user("Me", 1234);
console.log(myUser.getUsername()); // Me
myUser.setUsername("NotMe");
console.log(myUser.getUsername()); // NotMe
console.log(myUser.checkPassword(1000)); // false
console.log(myUser.checkPassword(1234)); // true
view raw closureExample.js hosted with ❤ by GitHub

Summing up

Scope refers to a variable’s accessibility. It can either be public (defined outside any functions and curly braces and accessible anywhere in the code) or local (defined inside a function or block and accessible only inside said function or block). Closures are functions defined inside other functions and can be used to access a function’s private variables from outside its own scope.