In arrow functions, this
is whatever this
refers to in the context where the arrow function was created. So, the code below, which produces a bunch of undefined
's, can be fixed by converting the anonymous function into an arrow function. →
const counter = {numbers: [1, 2, 3, 4], animal:'owl'};
counter.count = function() {
this.numbers.forEach(function(n) {
console.log(n, this.animal + (n > 1 ? 's' : ''));
});
};
counter.count(); // uh-oh... prints undefined 4 times!!!!
Fixed by arrow functions: →
counter.count = function() {
this.numbers.forEach((n) => {
// this refers to the this in count!
console.log(n, this.animal + (n > 1 ? 's' : ''));
});
}; // ah, saved by an arrow function
Well, if arrow functions are so great, why don't we use arrow functions all of the time? →
There are some places where they don't work quite right.
addEventListener
callbacks where you want this
to refer to the element that generated the event
But why not? →
Remember, arrow functions do not bind this
to a new value, and instead gets its this
from the enclosing scope
In the following code, we try to use an arrow function as a constructor. →
const Cat = (name) => {
this.name = name;
}
Creating the function works fine, but if we try to use it with new
:
var c = new Cat();
We get…
var c = new Cat();
^
TypeError: Cat is not a constructor
Instead, use the usual function declaration to create constructors:
function Cat(name) {
this.name = name;
}
What is the output of this code? →
function Cat(name) {
this.name = name;
}
Cat.prototype.meow = (() => {
console.log(this.name, 'meows');
});
var c = new Cat('paw newman');
c.meow();
undefined meows
this
this
remains the same as the this
in the containing context / scopeWhat's the output of this code? →
const cat = {
sound: 'meow',
meow: () => {console.log(this.sound);}
};
cat.meow();
// once again...
undefined
addEventListener
To be complete… be careful when using arrow functions and addEventListener
→
Starting with this code:
const button = document.createElement('button');
document.body.appendChild(button).textContent = 'Click Me';
The following listeners alert different messages!
// alerts window object (essentially global)
button.addEventListener('click', () => {alert(this)});
// alerts button element
button.addEventListener('click', function() {alert(this)});
this
in your event handler to reference the element event's target element, then use function expressionsthis
, and instead use the this from the surrounding context