Clarifying question about OOJS 1: arrow functions to define new method outside constructor

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?

Thank you in advance!

PS full script section here if it helps: https://jsfiddle.net/rxob9syn/

Hi @scipius02 :wave:

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:

  1. Just use a traditional function like in your first example.
  2. Move the arrow function inside the constructor
function Shape(name, sides, sideLength) {
  this.name = name;
  this.sides = sides;
  this.sideLength = sideLength;
  this.calcPerimeter = () => console.log(this.sides * this.sideLength);
}

This way the enclosing lexical context is the Shape constructor when the function is defined and therefore this refers to the constructor.

It’s a pretty complicated topic. Don’t hesitate to ask any further questions if something is unclear.

I hope that helps and have a nice day!
Michael

2 Likes

Got it, that makes a lot of sense. Thank you so much!

1 Like

Got it, that makes a lot of sense.

1 Like

thanks for that info @mikoMK

by the way are you one of @chrisdavidmills 's relative

you look like him

1 Like

Glad it helped!

One beard goes, another beard comes.
That’s a fundamental rule in the world of facial hair. :bearded_person:

But no, we are not related :grin:

1 Like

@mikoMK :joy: :joy: :joy: :joy:
long live the beard :joy:

Another recent post about the trickiness of this : Assessment wanted for Object basics 2 skill test!

Hi @mikoMK, is this the same phenomenon that appears in this assessment as well? https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features

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?

Yes, this is the same phenomenon.

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.

Michael