What are getters and setters for in ECMAScript 6 classes?

85,683

Solution 1

These setter and getter allow you to use the properties directly (without using the parenthesis)

var emp = new Employee("TruMan1");

if (emp.name) { 
  // uses the get method in the background
}

emp.name = "New name"; // uses the setter in the background

This is only to set and get the value of the property.

Solution 2

Getters and setters in ES6 serve the same purpose that they do in other languages... including ES5. ES5 already allows getters and setters via Object.defineProperty, though they're less clean and more cumbersome to use.

Effectively, getters and setters allow you to use standard property access notation for reads and writes while still having the ability to customize how the property is retrieved and mutated without needed explicit getter and setter methods.

In the Employee class above, this would mean you could access the name property like this:

console.log(someEmployee.name);

It would look like a normal property access, but it would actually call toUpperCase on the name before returning it. Similarly, doing this:

someEmployee.name = null;

would access the setter, and it would not modify the internal _name property because of the guard clause introduced in name's setter.

See also the general question Why use getters and setters? for more information about why being able to modify the functionality of member access is useful.

Solution 3

class Employee {

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

    doWork() {
      return `${this._name} is working`;
    }

    get name() {
      // when you get this by employeeInstance.name
      // the code below will be triggered
      // and you can do some logic here
      // just like `console.log` something you want
      console.log('get triggered!')
      return this._name.toUpperCase();
    }

    set name(newName) {
      // the same as `get`
      // when you employeeInstance.mame = 'xxx'
      // the code below will be trigged
      // and you can also do some logic 
      // like here is a `console.log` and `if check`
      console.log('set triggered!')
      if (newName) {
        this._name = newName;
      }
    }
  }

  const employeeInstance = new Employee('mike')
  employeeInstance.name
  employeeInstance.name = '' // this won't be successful, because the `if check`
  console.log(employeeInstance.name)

  // => 
  // get triggered
  // set triggered
  // get triggered
  // MIKE

Anyway the getter and setter is just like a spy. It spies the property of an object, so that you can do something, every time you get or set the value of the property.

Solution 4

ES6 getters and setters have a substantially different motivation than similar concepts in Java.

In Java, getters and setters allow a class to define a JavaBean. The point of getters and setters is that it allows the bean to have a completely orthogonal "interface" from that implied by public fields. So I can have a field "name" that is is NOT a JavaBean property, and I can have a JavaBean property "address" that is NOT a field.

JavaBean properties are also "discoverable" by thousands of frameworks (Hibernate for example) via Java reflection. Thus, getters and setters are part of a standard method for "exposing" bean properties.

Getters and setters, being functions, also have the value that they "abstract" the implementation. It can be EITHER a field or a computed ("synthetic") value. So if I have a bean property called "zipcode", that starts out as stored string. Now suppose I want to change it to be a value computed from address/city/state?

If I use a field, this code breaks:

      String zipcode = address.zipcode();

But if I use a getter, this does not break:

      String zipcode = address.getZipcode();

JavaScript doesn't have anything like JavaBeans. So far as I've read, the intended value of GET and SET is limited to the aforementions "synthetic" (computed) properties.

But it's somewhat better than java in that while Java doesn't allow you to compatibly convert a "field" to a method, ES6 GET and SET allows that.

That is, if I have:

       var zipcode = address.zipcode;

If I change zipcode from being a standard object property to a getter, the above code now calls the GET function.

Note that if I didn't include GET in the definition, this would NOT invoke the zipcode GET method. Instead, it would merely assign the function zipcode to the var.

So I think these are some important distinctions to understand betweeen Java and JavaScript ES6 getters and setters.

Share:
85,683

Related videos on Youtube

TruMan1
Author by

TruMan1

Updated on November 25, 2021

Comments

  • TruMan1
    TruMan1 over 2 years

    I am confused as to what the point of getters and setters are in ECMAScript 6 classes. What is the purpose? Below is an example I am referring to:

    class Employee {
    
        constructor(name) {
            this._name = name;
        }
    
        doWork() {
            return `${this._name} is working`;
        }
    
        get name() {
            return this._name.toUpperCase();
        }
    
        set name(newName){
            if(newName){ 
                this._name = newName;
            }
        }
    }
    
    • Arturo Torres Sánchez
      Arturo Torres Sánchez over 9 years
      It's similar to those in C#, if you happen to know about it.
    • Bergi
      Bergi almost 8 years
    • webdevinci
      webdevinci almost 7 years
      Good article explaining just this can be found at: coryrylan.com/blog/javascript-es6-class-syntax "In our class above we have a getter and setter for our name property. We use ‘_’ convention to create a backing field to store our name property. With out this every time get or set is called it would cause a stack overflow"... It also speaks of the variable not truly being 'private', but there are numerous new ways to create private vars in JS classes; my favorite is just using Typescript, but I've used the Symbol approach too
  • Krzysztof Borowy
    Krzysztof Borowy over 7 years
    Did You mean property instead of attribute? Bit confusing for me
  • Ray Toal
    Ray Toal over 7 years
    Good eye, @Krizzu. Attributes exist in JavaScript and are completely different things than properties. The answer does indeed refer to properties and not attributes. I've edited the answer. I don't think the answerer will mind. :)
  • Christof Kälin
    Christof Kälin about 7 years
    I'm not quite sure this really is such an advantage, it somehow hides the notion of using setters/getters. A client of a class may think it directly uses properties, where it's not appopriate, but I agree it adheres the information/detail hiding principle. Maybe if we use this consequently it makes usage easier and I just have to get used to it more...
  • Vignesh S
    Vignesh S almost 7 years
    Can you pass multiple parameters in a setter if so how do you use it? @David Laberge
  • Jim Doyle
    Jim Doyle about 6 years
    If you want to create setters and getters manually here's a good example from coryrylan.com/blog/javascript-es6-class-syntax Set: set name(newName) { this._name = newName; } Get: get name() { return this._name.toUpperCase(); }