Do You Know About Special Getters and Setters in JS Classes?

This blog is intended for developers who are familiar with JavaScript development and wants to learn about writing more clean and eloquent getters and setters in JS classes.

Data Integrity

JavaScript is expected to welcome encapsulation to the language soon with the introduction of privateclass fields, set to arrive in 2020 as part of ECMAScript 11 release. Feeling the excitement?

Please read my previous blog that describes this in detail: https://ahamedblogs.wordpress.com/2019/11/29/js-encapsulation-before-and-after-classes/

Technically, private class fields declared/defined in a JS class can only be accessed within the scope of that class and can only be accessed and modified indirectly via getters and setters outside the class. This concept is prevalent in many modern OOP languages but it is a brand-new concept to JavaScript.

Note: JS classes do not introduce new object-oriented inheritance model to the language. It merely serves as a syntactic-sugar over existing prototypical inheritance by bringing together the data and behavior.

Example of a JS class utilizing private class fields:


class Car {
#brand;
#model;
constructor(brand, model) {
this.#brand = brand;
this.#model = model;
}
getBrand() {
return this.#brand;
}
setBrand(brand) {
this.#brand = brand;
}
getModel() {
return this.#model;
}
setModel(model) {
this.#model = model;
}
}

view raw

Car.js

hosted with ❤ by GitHub


const car1 = new Car('Tesla', 'Model 3');
car1 instanceof Car; =>//true
car1.brand; //=>undefined
car1.model; //=>undefined
car1.getBrand(); //=>'Tesla'
car1.getModel(); //=>'Model 3'
//Propery check also fails – no detection. That is exactly what we want.
Object.keys(car1); //=>[]
'#brand' in car1; //=> false
car1.hasOwnProperty('#brand'); //=>false

view raw

Car.js

hosted with ❤ by GitHub

As you can see, we can now define/declare instance variables directly inside the class. When variables are prefixed with #, they are considered private instance fieldsand can only be accessed and modified via getters and setters like we have written above. And any attempt to detect private properties using built-in methods will fail.

Crux

In the above example, we have written perfect getters and settersgetBrandand getModelto access the private fields. However, there is another shorthand way of writing getters and setters. Introducing this specific-syntax is the crux of this blog. Its usage as follows:


class Car2 {
#brand;
#model;
constructor(brand, model) {
this.#brand = brand;
this.#model = model;
}
get brand() {
return this.#brand;
}
set brand(brand) {
this.#brand = brand;
}
get model() {
return this.#model;
}
set model(model) {
this.#model = model;
}
}
export default Car2;

view raw

Car2.js

hosted with ❤ by GitHub


const car2 = new Car2('Tesla', 'Model 3');
console.log(car2 instanceof Car2); //=>true
console.log(car2.brand); //=>'Tesla'
console.log(car2.model); //=>'Model 3'
car2.brand = 'Ford';
car2.model = 'GT';
console.log(car2.brand); //=>'Ford'
console.log(car2.model); //=> 'GT'

view raw

Car2.js

hosted with ❤ by GitHub

Utilizing this syntax will help access and modify the private fields directly by calling the properties on the object, essentially eliminating the need to invoke getters and setters. 

Conclusion

In this blog, we have looked at more eloquently way to write getters and setters in JavaScript. I hope you make use of this in your future projects!

My Github repository containing the above example can be found here: https://github.com/ahamedali95/getters-and-setters-in-JS-classes

Leave a comment