Reputation: 171
function makeCounter() {
let count = 0;
return function() {
return count++;
}
}
makeCounter()
alert(makeCounter()) // alerts the function itself
Why can't I call the function like above and make it work?
Why I have to save the function to a variable first like this?
function makeCounter() {
let count = 0;
return function() {
return count++;
}
}
let counter = makeCounter()
counter()
alert(counter())
What's the difference?
Upvotes: 0
Views: 516
Reputation: 5603
When you call makeCounter()
like this, It will be executed of course but this function return a function. Every Javascript function always return something, when the keyword return
isn't present in the function undefined
.
So in your case, you are implementing the Module Design Pattern which allow you to create PRIVATE variables which are not visible outside of your function in this case precisely the hidden variable is count
.
As you wan't to maintain a counter available as many time the function is executer to have the effect of incrementation. You want to return a function which have access to that private variable so the parttern is like this
function X() {
// private data are define here
let name = "John doe",
let age = 52;
// public data are define in the return object
return {
getName: () => return name,
setName: (newName) => name = newName
}
}
As you can see you can't access name variable directly after you have executed the X
function. but the returned object give you access to an object which have some helpfull method which manipulate private data in the X
function.
So here you have define the makeCounter
functon as this function need to keep track of the counter
that data is same as private inside of the function so the returned function can have access to that private data so when the return function is executed the counter can be increment.
As the counter can be call multiple time you have to same that returned function in a variable so you can call it whenever you want and the counter
inside of the makeCounter
function will be updated.
function makeCounter() {
let count = 0;
return function() {
return count++;
}
}
const counter = makeCounter();
console.log(counter()); // log 0
console.log(counter()); // log 1
console.log(counter()); // log 2
console.log(counter()); // log 3
But if you don't save the returned function in a variable you'll have to call a function only once and loose the reference to the counter and every time you call the makeCounter()()
It will be a new reference of counter
function makeCounter() {
let count = 0;
return function() {
return count++;
}
}
console.log(makeCounter()()); // log 0
console.log(makeCounter()()); // log 0
console.log(makeCounter()()); // log 0
console.log(makeCounter()()); // log 0
Upvotes: 1
Reputation: 521
A function might return a function. As far as I remember, such a design was used to create a stateful function back in the day and is still being used by transpilers to provide support for older Javascript environments.
For example, if you'd like to create a function that returns a number and manipulates the number for later calls. The function should return another function to encapsulate the state of your number, otherwise, it cannot remember the previous value of the number.
So, with that said, let's create a stateful function:
let statefulFunction = () => {
let number = 0;
return {
add(amount = 1) {
number += 1;
return number;
}
}
},
statefulFunctionInstance = statefulFunction();
document.querySelector('button').addEventListener('click', event => {
event.target.innerText = statefulFunctionInstance.add();
});
<button>0</button>
I remember using this design to encapsulate functions like nextSlide
in a slide or something similar. It can be used to store DOM queries, and form values, etc.
Upvotes: 0
Reputation: 62
You are indeed returning a function, and you would like to invoke the returned function, so main function will create the function in return statement but it doesn't invoke, to do that functionality you should invoke the returned function hence u need to store and call it!. To make it more clear try the function typeof in JavaScript.
Please correct me if I'm wrong!
Upvotes: 0