The concept of closure is one that has been difficult to get a simplified explanation of its functionality and core concept even with advanced developers.
To understand the concept of closure, you should have a fundamental understanding of JavaScript Functions, scopes, and lexical scope.
Your understanding of these concepts will give you a clearer understanding of JavaScript Closure.
In this article, we will simplify JavaScript Closure with a practical approach to its functionality. Additionally, you should be able to understand what closure is and get a practical implementation of it.
What is Scope in JavaScript?
Scope in JavaScript refers to the visibility and accessibility of variables, objects, and functions from different parts of the code.
In other words, scope simply tells us which variable is visible or can be referenced in a given code where it is been declared.
JavaScript has broadly two types of scope:
Global scope
Local scope
Global scope
Variables that are declared outside of a function have a global scope. This simply means they are visible everywhere and can be accessed and changed from anywhere in the codebase.
Let’s look at an example:
js
1: let firstName = "Success" //this is has a global scope
2: let lastName = "Ibekwe" // this has a global scope
3: function welcomeUser() {
4: let message = "Welcome";
5: console.log(message + " " + firstName + " " + lastName);
}
6: welcomeUser()
/*
calling this function will print out " Welcome Success Ibekwe "
*/
From the code snippet above, the firstName and lastName variables have a global scope because they are declared outside of the welcomeUser() function.
The point of the variable declaration determines the accessibility of the variable. If a variable is declared in the global scope, it's accessible within the entire object.
For instance, the two variables firstName and lastName, as you can see in the console.log inside the welcomeUser() we were able to make reference to the firstName and lastName variables.
Local scope
Variables declared within a function have local scope. This simply means that they are only visible and can be referenced within the scope of that function where it is been declared.
This is made possible by the use of the let or const keyword which was introduced in ES6
let’s look at an example using our previous code.
js
1: let firstName = "Success" //this is has a global scope
2: let lastName = "Ibekwe" // this has a global scope
3: function welcomeUser() {
4: let message = "Welcome";
5: console.log(message + " " + firstName + " " + lastName);
}
6: welcomeUser()
/*
calling this function will print out " Welcome Success Ibekwe " in the browser console
*/
7: console.log(message) // this will throw an error in the browser console saying (Uncaught ReferenceError: message is not defined).
You will notice that inside of the welcomeUser() function, we declared a variable message on line 4.
The message variable has a local scope, so it can’t be accessed or changed from outside of the welcomeUser() function. It can only be referenced or changed within the welcomeUser() function where it is declared.
In line 7, we tried to access the message variable from outside of the welcomeUser() function but it will get throw an error. (Uncaught ReferenceError: message is not defined).
What Is Lexical Scope?
The lexical scope shows how a nested function (known as the child) can have access to the variables defined in the outer function that surrounds it (known as its parent).
While the parent function can’t access the variables defined inside of the child's function. If we have a child function within a parent function, the child function has access to the scope of the parent function and also has access to the global variables.
This is often confused with closure but it's not. Lexical scope is an important part of closure but it is not Closure entirely.
Let’s take a look at a code example to further simplify the definition.
js
1: function parentFunc() {
2: let x = 10;
3: function childFunc() {
4: let y = 20;
5: console.log(x); // this will output 10 in the console.
}
6: childFunc();
7: console.log(y) // this will throw an error
}
8: parentFunc();
From the code example, we created a function called parentFunc() on line 1, this is the parent function because it has the childFunc() function in line 3 declared inside of it.
So childFunc() is a child to the parentFunc(). On line 2, we declared a variable x inside of the parentFunc(), and on line 4, we declared a variable y but this time inside of the childFunc().
From line 5, we were able to access the variable x from within the childFunc(), even though the x variable was declared in parentFunc() and not in the childFunc().
But in line 7, we tried to access the variable y outside of the childFunc(), but we couldn’t access it. it threw an error.
From the example, Lexical scope lets us know that the child function has access to the variables declared in the parent function, but the parent function does not have access to the variables declared inside of the child function.
Now that you understand the concept of scope and lexical scope, let's dive fully into JavaScript Closure.
What is Closure in JavaScript?
Let’s take an example of the MDN definition of Closures.
A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function’s scope from an inner function. In JavaScript, closures are created every time a function is created, at function creation time.
Closure in JavaScript is a function that has access to the variables declared in its parent scope, even after the parent function is closed.
A closure can basically access variables declared within its function, can also access variables declared in its parent function and also has access to variables declared outside its parent scope, but the reverse is not the case.
Let’s take a look at a code example.
js
1: let global = 1
2: function parentFunc() {
3: let x = 3;
4: console.log(global)
5: console.log(x)
6: function childFunc() {
7: console.log(global += 5);
8: console.log(x += 1)
}
9: return childFunc()
}
10: let result = parentFunc();
11: console.log(result);
12: result();// this will output 6 and 4 in the console
From the code snippet, we declared a global variable that is accessible by the parent function and child function on Line 4 and Line 7.
Furthermore, we also noticed that the childfunc() function was able to access both the global variable (global) and the variable (x) declared inside the parent function.
But what makes closure different, is the fact that it could still access the variable declared in its parent function even after the parent function is closed.
For more clarification, take a look at line 10 where we assigned the parentFunc to the result variable. The parentFunc() is closed here but we could still access its variable with the result variable.
If we log the result function we will get the childFunc()
js
console.log(result) // this will output the childFunc
So when we call result() on line 12 we will get the result of the console.log on lines 7 and 8.
Therefore, even after the external function ceases to exist, the internal function has access to the variables defined in the Scope by the external function.
The result() function is the JavaScript closure because it could still access the variable inside the parentFunc() after it is returned by making the variable a private variable that can only be accessed by it.
Uses Of JavaScript Closures
JavaScript Closure is a powerful addition to the JavaScript language because it helps to group data with functions that operate in that data.
If you are familiar with Object-Oriented Programming (OOP) this might sound familiar to you because anywhere that objects are used, closures can be used there too in JavaScript.
Secondly, JavaScript closures are used to make variables private, as the variables defined within a closure are not accessible by functions outside of it. But the closures have access to the variables within its scope and outside of its scope.
Let’s see the following example for a better understanding of Closure using Immediately Invoke Function Expression(IIFE), they are often used to give examples of closure.
js
const counter = (() => {
})() // we invoked the function by addding the parenthesis
Let’s take it further by defining some values inside of the function:
js
const counter = (()=>{
let count = 0;
console.log(`YOur count starts at ${count}`);
return () => {
count += 1;
console.log(count)
}
})()
counter()// we will get 1 in console because the count variable has been incremented by 1
The code snippet declared a count variable and logged it into the console. Next, we returned an anonymous function where we incremented the count variable and logged the value of the count, and will see the value of the first console. We were able to see that in the console because the function was already invoked.
Now, the counter is equal to the function. So if we call the counter function, we will get the value of 1 in the console, because the count variable has been incremented.
So each time we call the counter function we will continue to increment the count variable. Therefore, you can see that even when a function has been closed, we could still access the value of the count variable inside the function using the counter function.
Conclusion
JavaScript Closure is a very specialized concept in JavaScript, and for every javascript developer, it is a very important tool if they have an understanding of its basic concept and implementation.
In this article, we learned about scope and how they are implemented in JavaScript. Lastly, we move on to learn about closure and how to implement them in our code.
If you’re working on JavaScript projects and need reliable hosting, our JavaScript Hosting services can offer the support and performance you need.
Let us know your thoughts in the comment section.
Frequently Asked Questions
Do I need to know how to code to use WordPress?
Definitely not. There’s no need to learn coding, since most WordPress users aren’t developers. There’s many plugins and themes you can use to customize your website without coding.
How secure is PHP?
PHP has an excellent security reputation and the developers are constantly making updates. Plus, you’ll benefit from additional security measures for your site by opting for a managed hosting package.
Do I need web developer skills to use Shopify or WooCommerce?
No. Both platforms welcome beginners, but you might get more out of WooCommerce’s extensions if you’ve got some previous experience.
Can I contact the PHP developers?
Not directly, however, over on PHP.net you’ll find an extensive range of patch update information, forums, and articles that will answer the majority of your technical questions.
I am a software developer who is geared toward building high-performing and innovative products following best practices and industry standards. Follow me: Twitter, Facebook, LinkedIn
View all posts by Solomon Eseme