0

I am new to JavaScript and would like to understand something about functions. Why is it that when calling a function to run, one usually has to end of with parenthesis (), and if not it will just display the contents of the function. But when binding an event listener to a element, one may not use parenthesis when calling the function and if they are used it will run as soon as the page loads. (same is true when using the setTimeout or SetInterval function).

Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
Yossi Sternlicht
  • 740
  • 1
  • 6
  • 17
  • 3
    When you're initializing an event listener, or initializing a timeout or interval you're _not_ calling the function. You're passing the function to the framework to be called at a later designated time. – Patrick Roberts Nov 24 '18 at 19:11
  • So when is the function ever called – Yossi Sternlicht Nov 24 '18 at 19:14
  • As I already said, it's called by the framework, not by you. – Patrick Roberts Nov 24 '18 at 19:16
  • Basically, thats how javascript works. It knows to call it by itself – Yossi Sternlicht Nov 24 '18 at 19:20
  • @PatrickRoberts JavaScript is not a framework. The invocation of the referenced handler is handled by the DOM element - - it really is not part of JavaScript at all. – Scott Marcus Nov 24 '18 at 19:29
  • 1
    @ScottMarcus The DOM (or whatever place where you register the callback) can be said to be a framework – Bergi Nov 24 '18 at 19:34
  • @Bergi I think it has to be more specific that that. JQuery, for example, is a library, while Angular is a framework. The DOM is an API, not a framework. – Scott Marcus Nov 24 '18 at 19:40
  • APIs and frameworks are not mutually exclusive. – Patrick Roberts Nov 24 '18 at 19:42
  • @PatrickRoberts As a general rule, they are. https://stackoverflow.com/questions/724380/framework-vs-api – Scott Marcus Nov 24 '18 at 19:43
  • _"A framework does introduce the notion of [inversion of control](http://en.wikipedia.org/wiki/Inversion_of_control)"_ which is exactly what we're talking about here. But enough about semantics, this comment chain is getting ridiculous and the point of my original comment is still valid, even if you disagree with the particular use of terminology. – Patrick Roberts Nov 24 '18 at 19:44

2 Answers2

1

It's actually pretty simple once you understand that, in JavaScript, functions are data as well as units of invocable code. That means that you can pass them around, just as if you were passing the number 10 or the string "test".

  • When invoking a function, you must include parenthesis.

    foo(); // Invokes the foo function

  • When referencing a function (as data to be used somewhere), you don't. Event callbacks are examples of function referencing. In the following example, the string "click" and the function foo are being passed as arguments (data) to the .addEventListener() method of some element. That element, would now have foo registered in as a callback function to call if/when that element's click event occurs. We don't want to invoke foo right now, we just want to let the element know what function to possibly invoke later.

    element.addEventListener("click", foo); // References foo as the click event callback

    • Now, things can get a bit more complicated because functions can return a value when they are done running and that value (data) can also be another function. In those cases, we want to invoke a function in order to get the function that it returns back (as data):

function returnAfunction(){
  // When this function is invoked, it will return
  // (as data) another function:
  return function(){
    console.log("You did it!");
  };
}

// Here, notice that the second argument does have parenthesis after it.
// This is because we want the function to run right now and whatever its
// returned value is will then become the actual event callback for the
// button element.
document.querySelector("button").addEventListener("click", returnAfunction());
<button type="button">Click me!</button>
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
  • Thanx. i just didnt understand that once you referenced it, the framework will call it later automatically like Patrick Roberts pointed out – Yossi Sternlicht Nov 24 '18 at 19:25
  • 1
    @JoeStarbright That is what `.addEventListener()` does. It's job is to **add** an event listener (function) to the element so that when the referenced event (`click` in this case) occurs, any registered handlers will automatically be invoked. The idea of function referencing is central to how JavaScript operates. – Scott Marcus Nov 24 '18 at 19:26
0

I think it is because when you define a function, you may pass it some parameters like

const isUserValid = (username, password) => {
  for (i = 0; i < database.length; i++) {
    if (database[i].username === username && database[i].password === password) {
      return true;
    }
  }
  return false;
}

and so is true for when you want to execute the function. But when you add an event listener, then you are automatically calling the function to execute on (i.e. click)

Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153