Yeison Daza
3 min read

Understanding Getters and Setters in JavaScript

Since ES2015, we have the ability to use getters and setters to define properties on our objects. In this post we’ll understand how they work.

Before reading this post, I recommend checking out:

Ready?

At this point, you should already know the behavior and attributes of object properties in JavaScript.

It’s worth clarifying that objects have three types of properties:

  • Data properties: Regular properties that contain data.
  • Accessor properties: Properties that change the standard behavior of [[get]] and [[put]]
  • Internal properties: Internal language properties, such as [[prototype]], [[get]], or [[put]], among others.

What Are Getters and Setters

A function that gets the value of a property is called a getter, and one that sets the value of a property is called a setter.

This feature was implemented in ES2015, allowing us to modify the normal behavior of setting or getting the value of a property. These are known as accessor properties.

How They Work

Sometimes we want values based on other values, and that’s where data accessors come in really handy.

To create them, we use the get and set keywords.

const obj = {
  get prop() {
    return this.__prop__;
  },
  set prop(value) {
    this.__prop__ = value * 2;
  },
};

obj.prop = 12;

console.log(obj.prop); //24

We created an object with a single property that has a getter and a setter. This way, every time we set a value for prop, it gets multiplied by two.

Note: I used prop by convention, but it doesn’t mean it’s a special value — it’s just a regular value.

Another way to create an accessor property is explicitly using Object.defineProperty.

const obj = {};

Object.defineProperty(obj, //objeto target
  'prop', //nombre propiedad
  {
    enumerable: true,
    configurable: true,
    get prop() { //getter
      return this.__prop__;
    },
    set prop(value) { //setter
      this.__prop__ = value * 2;
    },
  });
obj.prop = 12;

var atr = Object.getOwnPropertyDescriptor(obj, 'prop')
console.log(atr);

The advantage of this approach is that we can set the attributes we want the property to have.

Characteristics

An accessor property only has the configurable and enumerable attributes. If we look at its attributes, we’ll see this:

[object Object] {
    configurable: true,
    enumerable: true,
    get: function get() {
      return this.__prop__;
    },
    set: function set(value) {
      this.__prop__ = value * 2;
    }
}

This means the value can’t be overwritten unless the function’s setter is used (it’s recommended to define both setter and getter).

If strict mode is not used and you try to modify the value, it will be a silent error.

Another important characteristic is that if a property with the same name is set at a higher level in the prototype chain, the accessor property will be the one that takes precedence.

Let’s look at one last example.

let persona = {
  nombre: 'Yeison',
  apellido: 'Daza',
  get nombreCompleto() {
    return `${nombre} ${apellido}`
  },
  set nombreCompleto(nom) {
    const palabras = nom.split(' ');
    this.nombre = palabras[0] || '';
    this.apellido = palabras[1] || '';
  }
}

persona.nombreCompleto = 'Camilo Sanchez'

console.log(persona.nombre); //camilo
console.log(persona.apellido); //sanchez