How do they work together?
Closures, encapsulation, and higher-order functions are three cornerstone concepts in programming that, though distinct, often work hand in hand within JavaScript to craft more efficient and elegant code.
Let's delve into a LeetCode problem that, at first glance, appears straightforward but beautifully weaves together these three essential programming concepts.
So, let's create a function that returns another function!
Problem:
Create a function that returns a "Hello World" function.
Step One: Define the Outer Function.
We can define our outer function to have only one job. Encapsulate (more on what this means below) the logic for creating another function. This particular function will not take any parameters, it's sole purpose is to return another function that when invoked, will say, "Hello world".
function createHelloWorld() {
// This function will return another function.
}
Step Two: Create the Inner Function
Inside createHelloWorld
, we can define another function called inner function
for simplicity. This function is a one trick pony. It takes no parameters and when invoked, returns the string " Hello World". It's static and does one thing and one thing only, but it does it well.
function innerFunction(){
return "Hello World";
}
Step Three: Return the inner function
So now createHelloWorld
returns innerFunction
. We are handing over the function itself - not triggering its execution.
This is where the encapsulation magic happens, neatly packaging the inner function within the outer one.
function createHelloWorld() {
function innerFunction() {
return "Hello World";
}
return innerFunction;
}
Step Four: Utilizing the function
So what do we do now? Well we need to see how we can use this createHelloWorld
function. We invoke it and assign the result to a variable, f
in our case. The variable f
now holds a function, (our inner function) that we can call whenever we like.
const f = createHelloWorld();
console.log(f()); // Outputs: "Hello World"
function createHelloWorld() {
function innerFunction() {
return "Hello World";
}
return innerFunction;
}
const f = createHelloWorld()
And then we do call it:
//log variable f
console.log("f", f());
That was a lot of work just to log Hello World. Why is this useful?
Well turns out we used some pretty powerful concepts.
In simple terms
Encapsulation: Like a secret compartment, it involves tucking away details within a function, revealing only what's necessary. That's the role of our outer function.It not only hides complexity but also protects the integrity of the inner functions operations by not exposing any internal variables or states directly to the other parts of the code.
Closures: Think of it as the inner function holding onto a piece of the outer function like a keepsake.This allows the inner function to access and use variables from the outer function even after the outer function has executed and returned.
Higher-Order Functions: These are the VIPs of the function world, transforming functions by either accepting them as parameters or creating new ones to return. Higher order functions are used in event handlers and array methods. You'll find them everywhere.
Wrapping it up
This is one of the trickier topics to grasp for a beginner programmer but it really shows how flexible and powerful Javascript is as a programming language. Before you know it, you'll see these patterns popping up everywhere!
Keep at it, and happy coding!
Top comments (2)
Thanks! This is mostly for to get better at explaining concepts so I appreciate that feedback.