If I call the function once like this
var button = document.querySelector('button');
button.addEventListener('click', once);
function once() {
console.log('one');
button.removeEventListener('click', once);
}
It's calling only once.
But if I called like this once()
var button = document.querySelector('button');
button.addEventListener('click', once());
function once() {
console.log('one');
button.removeEventListener('click', once());
}
Exception throws
Exception: InternalError: too much recursion
Could you please explain why this is happening.
3 Answers 3
() after function name invoke's the function. So as button.addEventListener('click', once()); you are bind the return value of once() method which is undefined.
And since once() is called recursively without any break statement, you are getting the InternalError: too much recursion.
You should pass the function reference.
button.addEventListener('click', once);
For Additional Info:
4 Comments
too much recursion in the other caseIf you put () after the name of a variable holding a function, then you call the function.
If a function calls itself, then it will get called, call itself, call itself again and so on unto infinity. This is recursion. Doing something unto infinity will cause a computer to run out of memory, so it is undesirable.
JavaScript engines prevent this by throwing an exception when you try it.
(There are exceptions, of course, a function that calls itself conditionally can be very useful).
Comments
The first code is correct, because you register the function to be called.
The second code tries to register the result of the function call once(). This means you actually execute the function when you only want to register it. Now, in your function body, you do the same to deregister the callback. Here again, you call the function you are already executing and hence, you recurse infinitely.
()inside it()after the function name, the function is executed. And you don't want to be executed when you pass to method likeaddEventListenerorremoveEventListener, so just remove it.