10 votes

Why do the arrow functions won't return "this" object in a jquery event handler?

Consider the following simple jquery event handler code I've been using since ages:

$("body").on("click", ".dome .btn", function() {
	console.log(".dome .btn onclick::");
	console.log($(this));
});

The this object here returns the button element in question which is the proper way. But today, I decided to use arrow function just to upgrade myself with the modern times:

$("body").on("click", ".dome .btn", () => {
	console.log(".dome .btn onclick::");
	console.log($(this));
});

But in this case, the this object won't return the button element. It will return the window object instead which is the parent of all parents! What kind of atrocious quirk is this? Few days ago, someone on the /r/webdev subreddit told me that arrow function is just a modern way of writing the old function(){} syntax.

4 comments

  1. Wes
    (edited )
    Link
    Arrow functions are not identical to the function() syntax (function expressions). As you found, arrow functions do not rebind this. Sometimes you want that behaviour, but most of the time you...

    Arrow functions are not identical to the function() syntax (function expressions). As you found, arrow functions do not rebind this. Sometimes you want that behaviour, but most of the time you don't. Personally, I try to avoid using this whenever possible. Too many gotchas.

    Generally speaking, I think most people find the arrow function syntax to be much cleaner and more consistent. Though looking at the jQuery documentation, they do use the full function() syntax, so I'd guess that's the recommended best practice there. They're likely doing some rebinding behind the scenes.

    You might need to move away from jQuery to fully embrace arrow functions. There's no need if it's working for you, but I will say that between fetch and document.querySelector, vanilla JavaScript basically has you covered now.

    17 votes
  2. r-tae
    Link
    Whoever told you that they were just a modern alternative was just wrong, arrow functions have different semantics from function()s and don't bind their own this (meaning that this is equal to the...

    Whoever told you that they were just a modern alternative was just wrong, arrow functions have different semantics from function()s and don't bind their own this (meaning that this is equal to the current scope, which is currently window).

    You could do this instead:

    $("body").on("click", ".dome .btn", (event) => {
    	console.log(".dome .btn onclick::");
    	console.log(event.currentTarget);
    });
    
    16 votes
  3. devilized
    Link
    I think your question has been answered, but I just wanted to say that the idea that arrow functions and traditional function expressions are exactly equivalent is a common misconception. It's...

    I think your question has been answered, but I just wanted to say that the idea that arrow functions and traditional function expressions are exactly equivalent is a common misconception. It's actually one of the interview questions I commonly use for senior-level front-end/Javascript developers.

    8 votes
  4. Minori
    Link
    Arrow functions don't have their own this or arguments bindings (from this Stack overflow answer). I think your arrow function could be rewritten to return the element you want, but in general...

    Arrow functions don't have their own this or arguments bindings (from this Stack overflow answer). I think your arrow function could be rewritten to return the element you want, but in general arrow functions should be viewed as throwaway helpers to perform a specific routine. They're more like operators and functional programming than object oriented methods and function objects.

    Here's a link to the MDN page which covers arrow functions: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

    6 votes