Why dont we use arrow function inside object?

Tell us what’s happening:

  **Your code so far**

let dog = {
name: "Spot",
numLegs: 4,
sayLegs: function() {return "This dog has " + dog.numLegs + " legs.";}
};

dog.sayLegs();
  **Your browser information:**

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.72 Safari/537.36.

Challenge: Make Code More Reusable with the this Keyword

Link to the challenge:

because the this keyword works differently inside arrow functions, arrow functions don’t have their own this.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

arrow functions should not be used as methods

2 Likes

All functions have a scope, a private space where they can store their own variables. But traditional functions (as opposed to fat arrow functions) have an additional thing called a context, a sense of “who called me?” The this that @ieahleen talks about refers to that context.

But arrow functions don’t have a context of their own, they use the context of the thing that called them.

Now, if you don’t use this in your arrow functions, they work fine in objects. It only matters if you try to refer to the execution context, as it might not be what you think.

To add a few examples:

dog = {
  name: "Spot",
  numLegs: 4,
  sayLegs: () => `This dog has ${this.numLegs} legs.`,
};

dog.sayLegs();

"This dog has undefined legs."

Unlike functions defined with the function syntax, arrow functions do not have their own this (this is one of the reasons they exist). this is the context in which you execute the function. Which, if I run this in the browser, is the object window. So when you run dog.sayLegs(), this is undefined: window.numLegs is not a thing that exists.

dog = {
  name: "Spot",
  numLegs: 4,
  sayLegs: () => `This dog has ${dog.numLegs} legs.`,
};

dog.sayLegs();

"This dog has 4 legs."

When I run this, sayLegs looks for dog.numLegs: there’s an object that has been assigned to the name dog, and that object has the property numLegs.

This often isn’t quite what you want: maybe you want to create lots of dogs, and they’ve all got different numbers of legs, and maybe you have a function that creates those “dog” objects somewhere else in the program, or whatever. You’re not going to want write out

dog1 = { name: "Spot", numLegs: 4, sayLegs: () => `This dog has ${dog1.numLegs} legs.` };
dog2 = { name: "Mutant", numLegs: 27, sayLegs: () => `This dog has ${dog2.numLegs} legs.` };
dog3 = { name: "Tripod", numLegs: 3, sayLegs: () => `This dog has ${dog3.numLegs} legs.` };

Every time. What you want is that sayLegs just returns whatever the number of legs is on that specific object. So you need the function to have its own this: at that point, can do:

dog = {
  name: "Spot",
  numLegs: 4,
  sayLegs: function () {
    return `This dog has ${this.numLegs} legs.`
  },
};

No, they use the context (this) where they were defined, i.e. its static scope. Which is most likely undefined in strict mode, or the global object otherwise. There’s no special treatment of this in arrow functions, they just don’t define it in the first place like other functions do. If this is defined in an outer scope, it captures that value as an ordinary variable. Same treatment applies to super as well.

JS’s object model continues to be bonkers.