Search code examples
javascriptaddeventlistenerarrow-functions

What's the difference in the way these two event listener callbacks are added? Function VS arrow function calling the function


  1. What are the resulting effects one needs to be aware of with each of the approaches bellow?
  2. Is the arrow-function approach better if I needed to call a function whilst passing it an argument which isn't the triggering event itself?
document.querySelector('#element').addEventListener('click', () => myFunction1(param1));
document.querySelector('#element').addEventListener('click', myFunction2);

Solution

  • Calling the function inline, like with

    () => myFunction1(param1)
    

    will

    • call myFunction1 without a this of the element (if you're on the top level, this inside the function will be either the window object or undefined)
    • call myFunction with a parameter of param1 instead of a parameter of the click event

    The second approach is sometimes used as shorthand when you want to refer to the element the listener was attached to inside the listener, eg:

    function myFunction2() {
      this.remove();
    }
    document.querySelector('#element').addEventListener('click', myFunction2);
    <button id="element">click</button>

    To do the same sort of thing in the first approach, you'd either have to save the #element in a variable first, or select it again with querySelector.

    Is the arrow-function approach better if I needed to call a function whilst passing it an argument which isn't the triggering event itself?

    Yes, that's a very common way of doing it.

    Another way is to make a higher-order function, like so:

    const makeMyFunction1 = (param) => () => console.log(param);
    document.querySelector('#element').addEventListener('click', makeMyFunction1('foo'));
    <button id="element">click</button>

    Also keep in mind that if you want to be able to remove a listener later, you must use a named function:

    function myFunction2() {
      console.log('hi');
      this.removeEventListener('click', myFunction2);
    }
    document.querySelector('#element').addEventListener('click', myFunction2);
    <button id="element">click</button>