What is about "click"?

Hello,

I am having a confusion regarding “click”…

This code below works as I expected; when I clicked the button, the alert window popped out with cnt value displayed.

<!DOCTYPE html>
<html>
<body>
<button onclick="counter.inc()">Click Me</button>
<script>
      const counter = {
      cnt: 0,
      inc: function() {
          this.cnt++;
          alert(`cnt++: ${this.cnt}`)
      }
    }
</script>
</body>
</html>

And then, I tried the code below. It did not come out as I expected…
The alert window popped out right after the page was loaded, and then when I clicked the button, nothing happened …

<!DOCTYPE html>
<html>
<body>
<button>Click Me</button>
<script>
      const counter = {
      cnt: 0,
      inc: function() {
          this.cnt++;
          alert(`cnt++: ${this.cnt}`)
      }
    }
    
    document.getElementsByTagName("button")[0].addEventListener("click", counter.inc());
</script>
</body>
</html>

I am puzzled …

  1. why the alert window popped out right after the page?
  2. why “click” does not work to trigger alert window when the button was clicked?

Any ideas?

Thank you.

1 Like

here you are passing jn the output of the function, instead you just need tbe function, without ()

1 Like

You won’t get the results you think you will, but you can assign the inc function there. Right now, though, when you do

document.getElementsByTagName("button")[0].addEventListener("click", counter.inc());

What you are doing is immediately running that counter.inc() function and assigning any returned value to the click handler. Instead, remove the () to assign the function itself:

document.getElementsByTagName("button")[0].addEventListener("click", counter.inc );

And that will run the alert as you expect. However, you will encounter some strangeness, as the this keyword in the function may not be what you expect - you’re calling counter.inc from within the context of a click handler, so this will refer to that click handler.

A great book series, You Don’t Know JavaScript (Yet), talks about that in it’s section on Scope & Context.

1 Like

Thank you very much for the answer.

This is another puzzle I have in my head… when to pass/use “function” and when to pass/use “function()”… what is the best way to understand this? since I have seen many cases where “function” was passed to a method/function and sometimes “function()” is passed instead.

Thank you for the book. I was told about this book but have been so busy and procrastinated. I definitely need to read it.

1 Like

So, it is a challenging topic, but i think we can make some sense of it here.

The first thing to grasp is that functions, like strings or numbers or arrays, are simply data. They are things we can assign to a variable, and reference by that variable at any point. We can use them, or we can pass them into or out of function calls. Javascript sees absolutely no difference, just another kind of value.

This is what is meant when we refer to functions as first-class members of the language. They receive no special treatment, they’re just data.

So anytime we wish to refer to the function itself and not it’s evaluation, we can do so by simply providing the variable reference with no parentheses. When we provide a function to array.filter(...), for example, we are providing a reference yup

Thank you. so how should we look at this case below where both the function with/without parentheses work?

const popout = () => alert('hello');
const timeout = setTimeout(popout, 2000)   // works with popout
const popout = () => alert('hello');
const timeout = setTimeout(popout(), 2000)   // works with popout()

The first one will run popout after the timeout. The second will immediately run popout(), immediately display the alert, and after the timeout, there’s nothing for it to actually do.

1 Like

You are right. And what is the reason behind it?

setTimeout accepts a function, in this case popout, and will call it at the appropriate time

popout() is not a function, it’s the output of a function, in this case I think undefined - the function still has to execute to have the output so you still have the alert, but it executes before the timer

2 Likes

I see. Thank you for the explanation.
From what I understand now, it seems that popout is being treated as a reference to the function while popout() is being treated as an expression that produces a value or it behaves more like a callback function.

1 Like

somewhat yes, but not the last part, as setTimeout takes a callback to call after a timer

popout points in memory to the function, and is being called by the method after the appropriate time

and popout() is the expression to call a function, when you put the parenthesis after a function name, you are saying “put here the output of the function”

2 Likes

Thank you.
By summarizing your words, I guess the concept is like this:

  1. popout - a reference pointed to the memory of the function
  2. popout() - an output value of the function
1 Like