Use of Getters and Setters

Exercise

I am on the “Build a Library” project and I am starting to feel like I am getting to far into this without really knowing why I would a use a getter. Why wouldn’t I just access the property directly and when is it appropriate to use a getter?

Code:

class Media {
  constructor(key) {
    this._title;
    this._isCheckedOut = false;
    this._raitings = [];
  }
  get title() {
    return this._title;
  }
  get isCheckedOut() {
    return this._isCheckedOut;
  }
  get raitings() {
    return this._raitings;
  }
  set isCheckedOut(_isCheckedOut) {
    this._isCheckedOut = true;
  }
  toggleCheckOutStatus() {
    if (this._isCheckedOut === true) {
      this.isCheckedOut === false;
    }
    else if (this._isCheckedOut === false) {
      this.isCheckedOut === true;
    }
  }
  
  getAverageRating() {
    return this._raitings.reduce() / this._raitings.length;
  }
  
  
  addRaiting(raitingScore) {
    this._raitings.push(raitingScore);
  }
}

class Book extends Media {
  constructor(property1, property2, property3) {
    super(title);
      this.author;
        this.pages;
  }
  get author() {
    return this.author;
  }
  get pages() {
    return this.pages;
  }
}

class Movie extends Media {
  constructor(director, title, runTime) {
    super(title);
      this._director = '';
        this._runTime = 0;
          this.isCheckedOut = false;
            this.raitings = [];
  }
  get director() {
    return this._director;
  }
  get runTime() {
    return this._runTime;
  }
}

var historyOfEverything = new Book()

Good question, and a tough one. In ES it is pretty much code sugar. Is there an absolute need? One ventures, no. Can we design a script that makes intelligent use of the pattern? Yes. So it comes down to whether a programmer wants the challenge, and is willing to justify their choice of pattern.

Now the onus is on us to make this syntax feature weigh in with some value when we present our script. The buck stops here.

Now consider,

obj = {
    a: "a prop value"
}

versus,

obj = {
    _a: "a prop value",
    get a () {
        return this._a
    }
}

Essentially we are using a method to define a variable. What that creates is extensibility, meaning we can intercede in the return value. That value need not be constant, as would be a plain object property. We can inject a conditional that permits multiple return values.

3 Likes
 > obj = {
     _a: "",
     get a () {
       return this._a || "No value set for this property"
     }
   }
<- {_a: ""}
 > obj.a
<- "No value set for this property"
 > 

A little further…

 > obj = {
     _a: "",
     get a () {
       return this._a || "No value set for this property"
     },
     set a (x) {
       this._a += x.toString()
     }
   }
<- {_a: ""}
 > obj.a = "The meaning of life = "
<- "The meaning of life = "
 > obj.a = 42
<- 42
 > obj.a
<- "The meaning of life = 42"
 > 

This is a pattern that is going to take some justification. I’m not going to comment on that.

1 Like