AYM
AYM

Reputation: 171

Calling a function from variable

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

Answers (3)

Yves Kipondo
Yves Kipondo

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

Farsad
Farsad

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

hemanth
hemanth

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

Related Questions