0

I have some input elements to which I want to attach event listeners on the change event like so:

inputs.forEach(input => input.addEventListener('change', handleUpdate));

Now the handleUpdate handler function works when defined as a named function like this:

function handleUpdate() {
  console.log(this.value);
}

But this doesn't work when used with the fat arrow syntax like this:

const handleUpdate = () => console.log(this.value)

Now I know that this is set to the window object and one way to fix this is:

const handleUpdate = (ev) => console.log(ev.target.value);

But is this the right way to use fat arrow syntax in Javascript for event handlers or is it not recommended to use them in the first place?

Amit Erandole
  • 11,995
  • 23
  • 65
  • 103
  • 2
    `() => console.log(this.value)` is not really an anonymous function - its name would be set to `handleUpdate` (same as whatever you assign it to). And, yes, it's that function that goes to be a problem, since it has a lexically bound `this`. – VLAZ Dec 10 '16 at 13:14
  • You should keep in mind where really you define function literal. In JS all function definitions are hoisted to the top of the block by default. But if you define the function `handleUpdate` via function literal after you tried to use it as an event handler, it will not be hoisted and thus for `inputs.forEach(...)` expression the value of `handleUpdate` will be undefined. – Mister Spock Dec 10 '16 at 13:34

1 Answers1

3

es6 fat arrow notation maintains the value of "this" to the context where the function is created. If you want to change the value of "this" inside the function you should use "bind" on the function. And

const handleUpdate = () => console.log(this.value)

is not an anonymous function. It's a function called "handleUpdate". An anonymous function is a function that does not have a name assigned so you cannot call it execpt using it in the context it's defined. Example

target.addEventListener('click', () => { doSomeStuff() };

So your question does not compute in the context of the code you're posting.

Edit bind usage:

var handleUpdate = function() {console.log(this.value)};
handleUpdate = handleUpdate.bind(whatever_you_want_this_to_mean_inside_the_function);

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind

The methods call(), apply(), and bind() will not change the value of this in arrow functions. (In fact, the value of this inside of a function simply can’t be changed–it will be the same value as when the function was called.) If you need to bind to a different value, you’ll need to use a function expression.

TigOldBitties
  • 1,331
  • 9
  • 15