Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript Object-Oriented JavaScript Getters and Setters Setters

Chris Pulver
Chris Pulver
7,624 Points

Why prepend a class property?

In the "Setters" section of the "Object-Oriented Javascript" lesson, Ashley uses the following code to get/set the "owner" property.

class Pet {
  constructor(animal, age, breed, sound) {
    this.animal = animal;
    this.age = age;
    this.breed = breed;
    this.sound = sound;
  }

  get owner() {
    return this._owner;
  }

  set owner(owner) {
    this._owner = owner;
    console.log(`Setter called: ${owner}`);
  }

  speak() {
    console.log(this.sound)
  }
}

const ernie = new Pet ('dog', 1, 'pug', 'yip yip');
const vera = new Pet ('dog', 8, 'border collie', 'woof');

ernie.owner = "Chris";
console.log(ernie.owner);

I'm curious on a couple things. First, the reason, as she states, behind using "_owner" is we can't set the property name to be the same as the setter name (e.g. set owner (owner) {return this.owner = owner;}) So why not just use a different name like "ownerName" for the property? This would also eliminate the second issue, which is not being able to access the property through dot syntax without using a getter. So change the code to this:

set owner (owner) {
    this.ownerName = owner;
    console.log(`Setter called: ${owner}`);
  }

ernie.owner = "Chris";
console.log(ernie.ownerName);

This seems to give the same results, unless I am missing something.

In a different course I took outside of Treehouse, the reason given for prepending property names was: "Developers use an underscore before a property name to indicate a property or value should not be modified directly by other code. We recommend prepending all properties with an underscore, and creating setters for all attributes you want to access later in your code."

Can anyone with a little more experience than myself chime in? I'm guessing there are reasons other than what was stated in the video. Possibly having to do with more complex programs?

Thanks!

2 Answers

Firstly, you are correct in being able to use your suggestion. Personally I wouldn't, which I will provide an example for that may or may not be a reason to always use the underscore convention, but still I think is a good use case.

So to answer the first question, question you had. "Why not use a different name like ownerName?" Well, you most certainly can, although she used a different name too (i.e. _owner). So using ownerName doesn't better solve using _owner since neither option is equal to owner. Both are just alternatives.

As you or she stated, you cannot use the same name, which is due to circular referencing. Calling this.owner calls the getter get owner() { ... } which returns this.owner which calls the getter get owner() { ... }, see where I am headed? :] it just won't end.

The other course you took that had the info about prepending is correct. Conventionally in JavaScript, developers use the underscore to signify a "private" property or method, since there currently is no support for accessors. This lets other developers know, on your team, or consumers of your code, to not fiddle with properties/methods. For the most part, other developers will respect that and only use the "public" properties, that do not contain an underscore. So if you were to call it ownerName it would show up as such and not be read by others as "private". This can even effect yourself as you come back to the code later in time and not remember that you shouldn't mess with it.

My reasoning for keeping the property name the same with the underscore is for clarity and mapping of the two properties. Keeping the underscore will tell myself and others, that "assume this doesn't exist outside of the class". Also I can safely assume that the getter owner is related to _owner. So if you were to later extend owner to return an object instead of just a string, you can store more specific information under a different "private" property name, just as _ownerName. Example of what I mean:

// Current implementation (using _ownerName)
class Pet {
    ...
    get owner() {
        return this._ownerName
    }

    set owner(value) {
        this._ownerName = value;
    }
    ...
}

const myPet = new Pet(/* values here */)
myPet.owner = "Some Guy"
myPet.owner // "Some Guy"

Now we want a more complex owner because we have people for some reason:

class Person {
    constructor(firstName, lastName, age) {
        this.name = { firstName, lastName }
        this.age = age
    }
}

class Pet {
    ...
    get owner() {
        return this._ownerName
    }
    set owner(value) {
        this._ownerName = value
    }
    ...
}
const myPet = new Pet(/* values here */)
myPet.owner = new Person("Some", "Guy", 25)
myPet.owner // Person { name: { firstName: "Some", lastName: "Guy" }, age: 25 }

Now _ownerName doesn't make sense contextually, since it is storing an Owner Person, so now would you change the variable name everywhere throughout the class to make it make sense? Or maybe just update some documentation about what owner returns? I'd go with the latter

Hope that helps? Again, there is no "it must be this way" reasoning and nothing really stopping you from doing things the way you suggest other than convention and foresight. In development, not always, but most of the time, it is best to follow conventions and practices, since you will likely use code written by others, whom may follow the conventions, and have others use or work within the codebase you are working on.

Chris Pulver
Chris Pulver
7,624 Points

Thanks for your reply! I agree that it makes more sense to use the underscore and keep the names the same. I was just wondering since the reasoning in the video made it seem like it was a matter of necessity, and not for convention and continuity. At least that's the way I understood the explanation.

Appreciate the insight!

var language = { set current(name) { this.log.push(name); }, log: [] }

language.current = 'EN'; language.current = 'FA';

console.log(language.log);