When to not use ES6 Arrow functions

ES6 Arrow function is one of my favourite ES6 features. Its lexical this makes most sense in most cases.

 

The Problem:

 

However, I came a cross a case today where ES6 Arrow functions cause a bug when used as a JQuery callback. The code started like this:

$(document).on('blur', 'input[type=text]', function () {
  const $elem = $(this);
  if ($elem.val().length === 0) {
    // do something
  }
});

 

My ESLint config did not like the anonymous function so I changed it to arrow function:

$(document).on('blur', 'input[type=text]', () => {
  const $elem = $(this);
  if ($elem.val().length === 0) {
    // do something
  }
});

 

It looked all good and it passed all checks. But when a text input triggered a blur event, an error occurred complaining about $elem.val() is null.

I then put a breakpoint at the const line and inspected it in Chrome’s console. The $(this) still evaluated as an array of input elements (with one item) but strangely, once assigned, the $elem became something else (jquery.fn.init {}) and the $elem.val() evaluated null.

Ok, with ES6 arrow function’s Lexical This, it kind-of make sense. The lexical this in the example is actually not a Input element, it is pre-bound to the lexical this when the event handler is registered. Indeed, it is undefined if I put a console.log(this) there.  In this case, arrow function should be avoided because  lexical this is not desirable.

But how do we explain the results I had when inspecting with Chrome console ? It turned out that Chrome inspector is no good at resolving  this with the arrow function and keep reporting as if it is a normal callback function.

Conclusion:

  1. Take extra care when using ES6 arrow function when non-lexical this is desirable.
  2. Chrome browser inspector is not good at reporting Lexical This.