Hi, I'm Nicholas Johnson!

software engineer / trainer / AI enthusiast

Creating Read-Only & Virtual Attributes with JavaScript Getters and Setters

TL;DR Getters and setters let us create read only attributes of JSON objects. They work in all current browsers (except IE8), so you can use them today

Getters and Setters allow us to create functions to set attributes on our JavaScript objects. This allows us to create pseudoelements and store and retrieve computed values, much as we can with Ruby.

They allow us to write code such that, when we access an attribute of an object, we are actually calling a function. We can use them to create read only properties, write only properties, virtual properties, etc.

Browser support

Getters and setters were actually part of the ES5 specification, but browser support is only now catching up. They work in all the evergreen browsers (as you would expect) plus IE9.

Let’s make a cat

Here’s a nice cat called Miffy. You’ll notice that Miffy is just a plain old JSON object:

const cat = {
  name: 'Miffy',
  age: 12,
}

We can interact with Miffy as you would expect:

console.log(cat.name)
// outputs "Miffy"

Enter Getters

Getters allow us to create a function that will be called when we access an attribute, and which will retrieve a value. Let’s recode Miffy with a getter.

const cat = {
  get name() {
    return 'Miffy'
  },
  age: 12,
}

Note that we can still interact with our cat in exactly the same way:

console.log(cat.name)
;('Miffy')

The cat name is now immutable

Because we only have a getter, the value of cat.name cannot be changed. We have created a read only attribute of a JSON object:

cat.name = 'Hermionie'
console.log(cat.name)
;('Miffy')

Dynamic Values

We use getters to compute values dynamically and return them as though they were just attributes. Here we generate a description from the name and age. I can treat it just like an attribute:

  const cat = {
name "Miffy",
age: 12,
get description() {
  return [
    this.name,
    'is',
    this.age
  ].join(' ');
}
  };

  console.log(cat.description);
"Miffy is 12"

  cat.age = 45;
  console.log(cat.description);
"Miffy is 45"

Say our cat has a date of birth. We might dynamically generate an age attribute. It just works. We don’t need to manually call a function to compute it.

const cat = {
  dateOfBirth: new Date(1953, 12, 12),
  get age() {
    const now = new Date()
    return new Date(now - this.dateOfBirth).getFullYear() - 1970
  },
}

console.log(cat.age) // outputs 62. Poor old cat.

Setters

Setters let us set a value as though it were a property of the object.

const cat = {
  set name(name) {
    this._name = name
  },
}

Now we can set the value of name but not get it.

This lets us create virtual object properties

We can store this value anywhere.

The possibilities are endless.

Here we receive a dateOfBirth and store an age:

const cat = {
  set dateOfBirth(dateOfBirth) {
    const now = new Date()
    this.age = new Date(now - dateOfBirth).getFullYear() - 1970
  },
}

cat.dateOfBirth = new Date(1953, 12, 12)
console.log(cat.age)

Removing Setters and Getters

You can remove setters and getters altogether just like any other property using delete:

delete cat.dateOfBirth

console.log(cat.dateOfBirth)
undefined

This removes the virtual property altogether. It doesn’t just overwrite it with null, it’s completely gone.