0

Pretty basic question, but I'm not able to find a suitable answer anywhere as I'm not sure what verbiage to use. I'm trying to better understand what is happening here so I can keep myself from making this mistake again. As you can see on the last line, I'm trying to set the onclick event, but it immediately invokes the function. The solution is to remove the parenthesis, but what exactly is that doing? What is the difference between the two? Thanks for any help.


let element = document.querySelector("button");

function turnButtonRed (){
  element.style.backgroundColor = "red";
  element.style.color = "white";
  element.innerHTML = "Red Button"; 
}

element.onclick = turnButtonRed();

Federico klez Culloca
  • 26,308
  • 17
  • 56
  • 95
Ian C.
  • 78
  • 7

2 Answers2

1

think of turnButtonRed as a variable.

var turnButtonRed = function(){ return 2 };

Now, if you use that variable to pass it to onclick, for example, you have 2 possibilities

element.onclick = turnButtonRed; // this is setting onclick to a function
element.onclick = turnButtonRed(); // this is setting onclick to whatever the function returns (2 in this case).

You want onclick to be set to a function, not the result of a function. turnButtonRed() gives you the result of the function, turnButtonRed is the function itself.

TKoL
  • 13,158
  • 3
  • 39
  • 73
  • 1
    @IanC. The ability to pass functions as arguments to other functions, to set variables to be functions, etc, is one of the very strong points of Javascript compared to something like Java. It can sometimes be a bit of a mindbender, when functions return functions and so on, but it's worth it. – TKoL Jan 15 '20 at 16:24
  • 1
    @IanC. In JS and many other languages, functions can be treated like any other variable. We call these "First class functions". See https://en.wikipedia.org/wiki/First-class_function –  Jan 15 '20 at 16:48
1

In the statement element.onclick = turnButtonRed(); you are assigning the result of calling turnButtonRed, not that function itself. Simply remove the ().

Here is why. I refer you to the mighty Table of Operator Precedence!

Your line of code has two operators, assignment and function call. Let's see:

  • Function call is 20
  • Assignment is 3

We do things in operator precedence order, from highest to lowest. So what is happening is, you are evaluating the function call turnButtonRed() first, then assigning that result to the handler. Which isn't what you want.

Just remove the function call, and assign the function:

 element.onclick = turnButtonRed;

Here, we are not calling the function. Instead we assign the function itself as an event handler.

Now, the preferred, modern way of doing this is to add an event handler:

 element.addEventListener("click", turnButtonRed);

I leave it as an exercise to the reader to explore why this might be preferred.