7

I'm learning ES6, I just want to convert my ES5 knowledge to ES6.

here's my ES5 code:

function click() {
  this.className += ' grab';
  setTimeout(() => (this.className = 'remove'), 0);
};

and here's my ES6 code:

const click = () => {
  this.className += ' grab';
  setTimeout(() => (this.className = 'remove'), 0);
  console.log('RENDERING');
}

My problem is this.className += ' grab'; and setTimeout(() => (this.className = 'remove'), 0); didn't run the function. But console.log shows on the log.

Is this method don't work on arrow functions?

John
  • 1
  • 13
  • 98
  • 177
Japs
  • 977
  • 2
  • 10
  • 19
  • 3
    `this` is not a method, and is different inside an arrow function - read [documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) to understand the difference ... `didn't run the function` yes, it did, you just don't know what you're doing yet – Jaromanda X Mar 15 '19 at 04:12
  • 2
    `this` keyword functions differently in arrow functions. [Read this section](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_separate_this) of the documentation. – yqlim Mar 15 '19 at 04:19
  • 3
    Aside - Consider using `el.classList.add('grab')` (and `el.classList.remove('grab')`) instead of manipulating the string of class names manually. [more info](https://developer.mozilla.org/en-US/docs/Web/API/Element/classList) – James Mar 15 '19 at 04:27
  • 1
    This shows that not all functions should be converted to arrow functions just because arrow functions are cool :p arrow functions serve a specific purpose and should only be used as appropriate – Jaromanda X Mar 15 '19 at 04:31

6 Answers6

11

There's not really enough context to give you a good answer, but one thing stands out. Arrow functions maintain scope, so this inside function click() and const click may well be different. In the ES6 version, this will refer to whatever was this during the closure creation, which may not be what you want.

Arrow Functions at MDN clears it up:

An arrow function does not have its own this.

…Which means that this will be inherited from the declaring scope.

ES6 arrow functions aren't just a new way of declaring functions, and there's nothing inherently wrong with function myFunction(...) syntax, nor is it going away. Arrow functions avoid some verbosity when passing a function as an argument (e.g. to forEach) and avoid the need to rebind a function to a different this in some cases. Converting all function declarations to arrow syntax is not an upgrade.

adc
  • 557
  • 4
  • 13
  • @jaromanda-x Yeah, you're probably right, especially if you assume that the function is normally called as an object method, which is why it would even have a className property. Shrug. – adc Mar 15 '19 at 04:29
3

In Arrow Functions, this isn't the this you would expect. this in Arrow Functions is defined when you create the function - not when it is called. See here for more information on that.

Thanks to @Jaromanda X from the comments - In this case, keep using standard function notation (function() {...}) - i.e. just because you bought a new screwdriver, doesn't mean the old hammer isn't still the best tool for banging in nails

Aniket G
  • 3,471
  • 1
  • 13
  • 39
0

The reason is that you just need to slightly restructure things.

setTimeout(() => {this.className = 'remove'}, 0)

You have parenthesis vs curly braces.

your this may or may not work depending on how things are structured in the other code

Jon
  • 2,456
  • 21
  • 28
0
       const click = () => {
           console.log(this);
           this.className += ' grab';
          setTimeout(() => (this.className = 'remove'), 0);
          console.log('RENDERING');
      }
      click();

'this' in the arrow function represents from wherever it is called. for eg if i open the browser and goto console and type above code then 'this' will become window object since the function is called from global enviroment. Also arrow function doesnot have its own 'this'.

Kaushal Regmi
  • 108
  • 10
0

You can bind this for arrow function to access functions and data. Your code should be something like

const click = () => {
  this.className += ' grab';
  setTimeout(() => (this.className = 'remove'), 0);
  console.log('RENDERING');
}.bind(this)

It will bind this for arrow function and you can access those variable and functions.

ZearaeZ
  • 899
  • 8
  • 20
0

An arrow function expression is a syntactically compact alternative to a regular function expression, although without its own bindings to the this, arguments, super, or new.target keywords. Arrow function expressions are ill suited as methods, and they cannot be used as constructors.

Bathri Nathan
  • 1,101
  • 2
  • 13
  • 17