0

I'm trying to call a function without re-initializing (hope I used the correct word here) it every time I call it. So the first time it gets called, it should initialize, but after its initialized, it should just use that reference.

Here's the code I'm trying to do it with.

JSFiddle

console.clear();

function mainFunction(e) {
  var index = 0;

  function subFunction() {
    console.log(index++);
  }
  return subFunction();
}

window.addEventListener('click', mainFunction)

index should increase by one every time mainFunction gets called. The obvious solution, is to make index a global variable (or just out of mainFunction). But I need index to stay inmainFunction`.

How can I make index increment every time (using the same reference) mainFunction gets called?

I tried assigning mainFunction to a variable, then calling the variable in the event listener,

var test = mainFunction;
window.addEventListener('click', test)

but that didn't work. The results were the same.

Jessica
  • 9,379
  • 14
  • 65
  • 136

4 Answers4

3

You should correct the code as follows;

console.clear();

function mainFunction(e) {
  var index = 0;

  function subFunction() {
    console.log(index++);
  }
  return subFunction; // <<< don't invoke subfunction
}

window.addEventListener('click', mainFunction()) // <<< invoke mainfunction
Redu
  • 25,060
  • 6
  • 56
  • 76
  • That calls it right away, and doesn't call it afterwards. I already wrote this comment above. Not sure why still wrote this as an answer??? – Jessica Sep 25 '16 at 06:25
  • Don't you want `subFunction` to be called on each click? If so, this code achieves that – fvgs Sep 25 '16 at 06:27
  • @fvgs Oh. He's correct! I did `return subFunction()` i.e. with the parenthesis. Thanks! – Jessica Sep 25 '16 at 06:31
  • How can I make it not call right away, i.e. on page load? It should only get called when the user clicks? – Jessica Sep 25 '16 at 06:38
  • @Jessica You are adding the event listener when the page loads.. it only logs the next number on the console when the user clicks the mouse button. – Redu Sep 25 '16 at 06:42
  • But `mainFunction` gets called right away. if you log something out outside of `subFunction` but in `mainFunction`, it will get called on page load: https://jsfiddle.net/62j1oLpe/ – Jessica Sep 25 '16 at 06:55
  • Also, what is a good tutorial (book, video, or blog) that explains this whole concept (of returning a function and how it gets called etc.)? – Jessica Sep 25 '16 at 07:15
  • 1
    @Jessica I would advise you to read the Chapter 2 of [this book](http://pepa.holla.cz/wp-content/uploads/2016/08/The-Principles-of-Object-Oriented-JavaScript.pdf) Well.. this is most probably the "best" book written on fundamentals of JS. You should buy and read all of it.. – Redu Sep 25 '16 at 07:20
  • One more question... How would I call `mainFunction` regularly (not in an event)? i.e. how would I call `mainFunction` that `mainFunction` would call `subFunction`? I tried `mainFunction()` but it didn't call `subFunction` – Jessica Sep 25 '16 at 07:43
  • @Jessica In the above code the aim is to keep a variable called `index` in closure. `mainFunction` doesn't invoke `subFunction` but just return a definition of it to the click event listener. Even though `index` is defined in `mainFunction`, `subFunction` has access to the `index` variable (closure) so every time the click event listener invokes `subFunction` it logs the `index` value and increments it. You could have done `var test = mainFunction()` and `test` would become `subFunction` and every time you do `test()`, you get index logged at console and incremented.. – Redu Sep 25 '16 at 08:04
0

maybe try closures?

var main = (function () {
var index = 0;
return function () {return index += 1;}
})();

main()
main()

//index should be 2...

explain- The variable main is assigned the return value of a self-invoking function.

The self-invoking function only runs once. index initialize only once.

Tommy
  • 134
  • 9
0

If you don't want to make index global (or one scope higher regarding mainFunction), you can use a closure:

var mainFunction = (function () {
    var index = 0;
    return function () {return console.log(index++);}
})();
<button onclick="mainFunction()">Click</button>
Gerardo Furtado
  • 100,839
  • 9
  • 121
  • 171
0

Using OOP concept is the proper way to achieve this. The following should help you. If you want to do it in ES6 way follow this babel example

var mainFunction = function(val) {
  this.index = val //initialize this with the fn parameter or set a atatic value
}

mainFunction.prototype.subFunction = function() {
  return this.index++
}

var instance = new mainFunction(0)

window.addEventListener('click', function() {
  console.log(instance.subFunction())
})
<p>Click to see the result </p>
Pranesh Ravi
  • 18,642
  • 9
  • 46
  • 70