Hello, I ran into this issue when I tried to simplify my line for
’ Shape.prototype.calcPerimeter = function() {console.log(this.sides * this.sideLength);}’
into
‘Shape.prototype.calcPerimeter = () => console.log(this.sides * this.sideLength);’
The latter expression outputs NaN to the console, and no figures for the perimeter, so I assume this has to do with the fact that I’m not implicitly returning anything? Even if this were the case, why doesn’t it console log the perimeter before returning NaN? Lastly, is there any accepted way for inserting an arrow function here?
You have uncovered a tricky little difference between traditional functions and arrow function. Arrow functions don’t have their own binding to this. They get their this from the enclosing lexical context when they are defined. In your example that’s the global object. You can test this by replacing console.log(this.sides * this.sideLength); with just console.log(this); in both version. Do you see the difference?
Two things you can do:
Just use a traditional function like in your first example.
Down in the setControls() section: “For a bonus point, can you tell us why we’ve had to set let _this = this; in the position it is in? It is something to do with function scope.”
So is this a way of restricting the scope of this to the function level?
It’s not about restricting scopes, but about preserving this when changing scopes:
Outside of window.onkeydown = function(e) { ... } we are in the constructor’s scope. By doing let _this = this; we preserve the “constructor this” inside _this. By entering the event handler function, this now refers to the event handler scope. As we want to change values of the constructor and not the event object, we use our “constructor this” which we saved in _this.
MDN | this gives some detailed insight what gets assigned to this.
As the topic is rather complex, most of the time when you’re unsure and have a suspicion that the value of this could be the problem, just console.log(this) to see what it refers to.