Learnitweb

getter in JavaScript

1. Introduction

Sometimes, you may to access a property which is dynamically calculated. However, you can do this with the help of a method, but you are not willing to use a method. In such case, you can use get syntax.

Let us understand this with the help of an example. Suppose there is an object Salary. The Salary object has two properties basic and allowance. You want to have a third property gross which will be sum of basic and allowance salary components. You can use the get syntax in this case.

The get syntax binds an object property to a function that will be called when that property is accessed.

const salary = {
  basic: 10,
  allowance: 20,
  get gross() {
    return this.basic + this.allowance;
  },
};

console.log(salary.gross); // output is 30

2. Syntax

{get prop() { /* write your code here */ } }
{get [expression]() { /* write your code here */ } }

prop is the name of the property bind to the given function.

expression is the computed property name bind to the given function. This is available starting with ES2015.

3. Other important points about get syntax

  • In an object, property name bind to a function using get syntax can not be same as any other property. For example, if an object has property x then you can not have x with get syntax like get x(). If you try this in Chrome browser, you’ll see that the latest defined x wins.
  • It can have an number or a string as identifier.
  • It must have exactly zero parameters.

4. Using get syntax to create pseudo-property

In the following example, gross is a pseudo property for object salary.

const salary = {
  basic: 10,
  allowance: 20,
  get gross() {
    return this.basic + this.allowance;
  },
};

console.log(salary.gross); // output is 30

5. deleting a getter using delete operator

You can delete a getter using delete operator:

const salary = {
  basic: 10,
  allowance: 20,
  get gross() {
    return 1;
  },
};

delete salary.gross;

console.log(salary);

output
---------
{ basic: 10, allowance: 20 }

6. Defining a getter on existing objects using defineProperty

const salary = {
  basic: 10,
  allowance: 20,
};

Object.defineProperty(salary, "gross", {
  get: function () {
    return this.basic + this.allowance;
  },
});

console.log(salary.gross); // Output is 30

There is difference between using get syntax and defineProperty() when used with classes. When using get syntax, the property will be defined on the instance’s prototype. Whereas, while using Object.defineProperty() the property will be defined on the instance it is applied to.

class Salary {
  get gross() {
    return "gross salary";
  }
}

const obj = new Salary();
console.log(obj.gross); // gross

console.log(Object.getOwnPropertyDescriptor(obj, "gross")); //undefined

console.log(
  Object.getOwnPropertyDescriptor(Object.getPrototypeOf(obj), "gross")
);



Output
------
gross salary
undefined
{
  get: [Function: get gross],
  set: undefined,
  enumerable: false,
  configurable: true
}

7. Expression in get syntax property name

Starting with ES2015, expressions can be used as property name in get syntax.

let sal = "salary";
const salary = {
  basic: 10,
  allowance: 20,
  get ["my" + sal]() {
    return this.basic + this.allowance;
  },
};

console.log(salary.mysalary); // output is 30

8. memoized (smart) getters

A getter is not smart by default and calculates the value as soon as it is called. You can save the result and return it whenever it is called next time. Such getter is called smart getter or memoized getter. You can choose to memoized a getter if following conditions are met:

  • if the computed value is expensive to calculate.
  • once the value is calculated, it is not expected to change.
  • it is not needed at the moment but may be needed later.

In the following example, assume that the salary calculation is an expensive operation. We have modified the getter gross such that the salary is calculated whenever the gross is accessed for the first time. The result of computation is saved in result and whenever the gross is accessed next time, the saved result is returned.

const salary = {
  basic: 10,
  allowance: 20,
  get gross() {
    if (this.result == null || this.result == undefined) {
      console.log("Calculating result for the first time.");
      let grossSalary = this.basic + this.allowance;
      this.result = grossSalary;
      return this.result;
    } else {
      console.log("returning saved result");
      return this.result;
    }
  },
};

console.log(salary.gross);
console.log(salary.gross);
console.log(salary.gross);
console.log(salary.gross);

Output
------
Calculating result for the first time.
30
returning saved result
30
returning saved result
30
returning saved result
30