JerryMan228
JerryMan228

Reputation: 35

JS: Class getters/setters vs. just changing property directly

class Person {
  constructor(name) {
    this._name = name;
  }

  get name() {
    return this._name.toUpperCase();
  }

  set name(newName) {
    this._name = newName; 
  }
}

let newPerson  = new Person("mike") 

What is the benefit of a getter and setter? Can't I still get it via newPerson._name and get mike? And to set it, can't I just do newPerson._name = "Phil" to set it ?

Upvotes: 1

Views: 1050

Answers (2)

CertainPerformance
CertainPerformance

Reputation: 370779

Looking at the getter should provide you with a hint:

  get name() {
    return this._name.toUpperCase();
  }

It can allow you to perform possibly-complicated logic, disguised as a plain property lookup. For another example, consider if you had firstName and lastName properties instead - then, you can make name a getter/setter for the actual underlying properties:

class Person {
  constructor(name) {
    // Invoke the setter below
    this.name = name;
  }

  get name() {
    return this._firstName + ' ' + this._lastName;
  }

  set name(newName) {
    const [first, last] = newName.split(' ');
    this._firstName = first;
    this._lastName = last;
  }
}

let newPerson  = new Person("John Smith") 
console.log(newPerson.name);

This sort of functionality (running logic and returning something custom instead of returning just the plain property value) would be impossible without getters/setters.

That said, for your original code, except for the toUpperCase part, yeah, the getter/setter isn't really doing much for you.

can't I just do newPerson._name = "Phil" to set it ?

Yes, you can. Underscores are generally used to indicate that a property shouldn't be used external to a class, but they don't forbid it entirely. If you want to make a property truly private, use # private field syntax.

class Person {
  #firstName;
  #lastName;
  constructor(name) {
    // Invoke the setter below
    this.name = name;
  }

  get name() {
    return this.#firstName + ' ' + this.#lastName;
  }

  set name(newName) {
    const [first, last] = newName.split(' ');
    this.#firstName = first;
    this.#lastName = last;
  }
}

let newPerson  = new Person("John Smith") 
console.log(newPerson.name);

Upvotes: 3

Jordan Mann
Jordan Mann

Reputation: 477

There are a few benefits to encapsulation, including validating data (throwing an error if you set the wrong value) and formatting it appropriately (returning "User has no name" instead of undefined). It also means that if you decide to change how the object's data is handled, you can point a getter/setter to new data without having to update an outdated property constantly. If you prefer the syntax of properties, JavaScript has the Proxy object to implement these getter/setter features.

This article on encapsulation might be of use.

Upvotes: 0

Related Questions