Reputation: 20496
I have the following code:
class Pet {
constructor(name) {
this.petName = name;
}
}
Pet.prototype.speak = {
name: function() {
console.log(this.petName);
}
};
// -----------------------------------------------
const myPet = new Pet("Max");
myPet.speak.name();
I expect this code to print Max
, but instead it prints undefined
.
If I change the console.log to console.log(this);
it prints { name: [Function: name] }
. Which makes me think that function doesn't have access to the instance properties.
How can I ensure that this function has access to the instance?
Upvotes: 2
Views: 1608
Reputation: 141839
When you call a function like this: myPet.speak.name();
then inside that function this
refers to myPet.speak
. In your case that is an object with one property (name) whose value is a function.
If you make speak
itself be a function instead of an object, and use the property petName
instead of name
, it will work:
class Pet {
constructor(name) {
this.petName = name;
}
}
Pet.prototype.speak = function() {
// myPet has a `petName` property, but no `name` property
console.log(this.petName);
};
const myPet = new Pet("Max");
myPet.speak(); // this will be `myPet` inside the function
Upvotes: 1
Reputation: 30360
If you're targetting or have support for ES6 language features, one way to achieve what you want would be via a get
method combined with an arrow function
.
The get
method would be declared get speak()
which means it can be called without paranthesis. This method would return an object that contains a name()
arrow function. Use of the arrow function here allows you to access the enclosing Pet
instance via the this
keyword directly:
class Pet {
constructor(name) {
this.petName = name;
}
// Get method allows the speak method to be called without ()
get speak() {
return {
// Arrow function causes this.petName to refer to petName
// field of this class instance
name: () => {
console.log(this.petName);
}
}
}
}
const myPet = new Pet("Max");
myPet.speak.name();
const yourPet = new Pet("Min");
yourPet.speak.name();
Here is more information on the get method syntax and language feature.
Upvotes: 3