Question 56

Question

How would you implement a custom getter/setter using Object.defineProperty() or using proxies?

Answer

1. Object.defineProperty()

This approach is more straightforward but offers less flexibility than Proxies.

const myObject = {};

Object.defineProperty(myObject, 'value', {
  get: function() {
    console.log('Getting the value...');
    return this._value; // Access a private property _value 
  },
  set: function(newValue) {
    console.log('Setting the value...');
    this._value = newValue;
  }
});

myObject._value = 'Initial Value';
console.log(myObject.value); // Outputs "Getting the value...", then "Initial Value"

myObject.value = 'New Value'; 
console.log(myObject.value); // Outputs "Setting the value..."

Explanation:

  • We use Object.defineProperty to define a new property called value on myObject.

  • The get function is executed when you access myObject.value.

  • The set function is executed when you assign a new value using myObject.value = ....

  • A private property _value is used internally to store the actual value.

2. Proxies (More Powerful)

Proxies offer greater control and flexibility over property access.

const handler = {
  get: function(target, prop) {
    console.log(`Getting '${prop}'`);
    return target[prop];
  },
  set: function(target, prop, value) {
    console.log(`Setting '${prop}' to ${value}`);
    target[prop] = value;
    return true; // Indicates the operation succeeded
  }
};

const myProxy = new Proxy({}, handler);

myProxy.name = 'John';
console.log(myProxy.name); // Outputs "Getting 'name'"
myProxy.age = 30;
console.log(myProxy.age); // Outputs "Setting 'age' to 30"

Explanation:

  • We create a handler object that defines the behavior for our proxy.

  • The get and set functions in the handler are called whenever a property is accessed or modified.

  • We use new Proxy({}, handler) to create a proxy based on an empty object ({}) and our custom handler.

Choosing Between Object.defineProperty() and Proxies:

  • Object.defineProperty(): Simpler for basic getter/setter implementations.

  • Proxies: More powerful, allowing you to intercept any property operation (including delete, hasOwnProperty) and control how they behave. Great for complex scenarios like logging, validation, or modifying values before saving them.

Last updated