Letâs revisit arrow functions.
Arrow functions are not just a âshorthandâ for writing small stuff. They have some very specific and useful features.
JavaScript is full of situations where we need to write a small function thatâs executed somewhere else.
For instance:
arr.forEach(func)âfuncis executed byforEachfor every array item.setTimeout(func)âfuncis executed by the built-in scheduler.- â¦there are more.
Itâs in the very spirit of JavaScript to create a function and pass it somewhere.
And in such functions we usually donât want to leave the current context. Thatâs where arrow functions come in handy.
Arrow functions have no âthisâ
As we remember from the chapter Object methods, "this", arrow functions do not have this. If this is accessed, it is taken from the outside.
For instance, we can use it to iterate inside an object method:
let group = {
title: "Our Group",
students: ["John", "Pete", "Alice"],
showList() {
this.students.forEach(
student => alert(this.title + ': ' + student)
);
}
};
group.showList();
Here in forEach, the arrow function is used, so this.title in it is exactly the same as in the outer method showList. That is: group.title.
If we used a âregularâ function, there would be an error:
let group = {
title: "Our Group",
students: ["John", "Pete", "Alice"],
showList() {
this.students.forEach(function(student) {
// Error: Cannot read property 'title' of undefined
alert(this.title + ': ' + student);
});
}
};
group.showList();
The error occurs because forEach runs functions with this=undefined by default, so the attempt to access undefined.title is made.
That doesnât affect arrow functions, because they just donât have this.
newNot having this naturally means another limitation: arrow functions canât be used as constructors. They canât be called with new.
Thereâs a subtle difference between an arrow function => and a regular function called with .bind(this):
.bind(this)creates a âbound versionâ of the function.- The arrow
=>doesnât create any binding. The function simply doesnât havethis. The lookup ofthisis made exactly the same way as a regular variable search: in the outer lexical environment.
Arrows have no âargumentsâ
Arrow functions also have no arguments variable.
Thatâs great for decorators, when we need to forward a call with the current this and arguments.
For instance, defer(f, ms) gets a function and returns a wrapper around it that delays the call by ms milliseconds:
function defer(f, ms) {
return function() {
setTimeout(() => f.apply(this, arguments), ms);
};
}
function sayHi(who) {
alert('Hello, ' + who);
}
let sayHiDeferred = defer(sayHi, 2000);
sayHiDeferred("John"); // Hello, John after 2 seconds
The same without an arrow function would look like:
function defer(f, ms) {
return function(...args) {
let ctx = this;
setTimeout(function() {
return f.apply(ctx, args);
}, ms);
};
}
Here we had to create additional variables args and ctx so that the function inside setTimeout could take them.
Summary
Arrow functions:
- Do not have
this - Do not have
arguments - Canât be called with
new - They also donât have
super, but we didnât study it yet. We will on the chapter Class inheritance
Thatâs because they are meant for short pieces of code that do not have their own âcontextâ, but rather work in the current one. And they really shine in that use case.
Comments
<code>tag, for several lines â wrap them in<pre>tag, for more than 10 lines â use a sandbox (plnkr, jsbin, codepenâ¦)