0

This JavaScript class doesn't set the attributes using the constructor. For some reason, they come out as undefined. I'm really confused, because if I take out the set/get methods it works, but with the set/get methods , name/genus return undefined.

class Animal {
  constructor(genus, name){
    this.name = name;
    this.genus = genus;
  }
  
  // called when setting this.name (i.e. this.name = value)
  set name(name){
    console.log("you set name");
  }
  
  // Called when getting this.name
  get name(){
    console.log("you got name");
  }
  
    // Called when setting this.name (i.e. this.genus = value)
  set genus(genus){
    console.log("you set genus");
  }
  
  // called when getting this.genus
  get genus(){
    console.log("you got genus");
  }
  
  makeNoise(noise = ""){
    console.log(noise);
  }
  
  // Class method
  static _repr(){
    return "Animal Class";
  }
}
> let cat = new Animal("Feline", "Daisy");
you set name
you set genus
undefined
> cat
Animal {}
> cat.name
you got name
undefined
> cat.genus
you got genus
undefined
1
  • Uh, your getters don't return anything? Commented Nov 5, 2021 at 0:12

2 Answers 2

1

When you do this.name = name in the constructor, you're invoking the setter. If you want to save the value passed in the constructor arguments, and also save the value when the properties are assigned to outside (eg animal.name = 'foo'), you'll need to

  • Use a different property name to internally store the data - something other than name, which is the same property name as the getter/setter
  • Fix the getters and setters to get and set that internal property

class Animal {
  constructor(genus, name) {
    this._name = name;
    this._genus = genus;
  }
  set name(name) {
    console.log('setter invoked');
    this._name = name;
  }
  get name() {
    console.log('getter invoked');
    return this._name;
  }
  set genus(genus) {
    this._genus = genus;
  }
  get genus() {
    return this._genus;
  }
}

const a = new Animal('gen1', 'name1');
console.log(a.name);
a.name = 'name2';
console.log(a.name);

Sign up to request clarification or add additional context in comments.

1 Comment

So basically, prefix the class attributes with _ to avoid triggering the set/get functions.
0

Your get methods need to actually return the values. You're receiving undefined because all the getters are doing is console logging.

For instance:

get genus(){
    console.log("you got genus");
    return this.genus;
}

3 Comments

I tried to return values in the set/get methods, but it kept doing an infinite loop. But actually I think I see what my problem was now that I'm looking at it
Won't this code do an infinite loop? this.genus calls get genus() which returns this.genus and so on.
CaptainPerformance's answer nails it - although you're correct about the infinite loop! Usually you'd instantiate in the constructor to this._genus and the getter would be called genus etc

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.