0
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?

asked Nov 28, 2020 at 5:36
3
  • You have two functions (makeCounter and the function it returns) so need two invocations. Commented Nov 28, 2020 at 5:41
  • When you call makeCounter() directly, it returns a function that you do nothing with. But when you call alert(counter()) you had previously defined counter to be the return function. Commented Nov 28, 2020 at 5:42
  • 1
    I believe your question has been well answered. I just wanted to add that if you want makeCounter to go into use immediately, maybe you can use IIFE. Commented Nov 28, 2020 at 6:19

3 Answers 3

1

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

answered Nov 28, 2020 at 6:31
Sign up to request clarification or add additional context in comments.

Comments

0

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!

answered Nov 28, 2020 at 5:44

3 Comments

Should be in comments but im upvoting.
No code. No code just some wording. But meant it was me who upvoted.
Hence the upvote. But these are comments. Also you have enough rep to answer just not to upvote.
0

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.

answered Nov 28, 2020 at 5:52

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.