Search code examples
javascriptgetterdefineproperty

javascript - add and delete smart getter programmatically


I'm trying to programmatically add and delete (for caching purposes) getters from an object. I'm adding a getter like this:

Object.defineProperty(obj, 'text', {
  get: getter
})

obj.text should only be evaluated the first time it's accessed, and the calculated value cached for subsequent calls.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get shows how to implement a smart getter like this:

get notifier() {
  delete this.notifier;
  return this.notifier = document.getElementById('bookmarked-notification-anchor');
}

I can't use delete this.text inside my getter function however. What I've found is, that this is the prototype of the Object rather than the instance - is that correct? And if so, how can I delete the getter of the instance and replace it with the calculated value?

edit:

As per the comments, the getter and object looks something like this:

var obj = {}
obj.value = '2018-04-21T12:00:00Z000'

Object.defineProperty(obj, 'text', {
  get: function () {
    delete this.text  // doesn't seem to work

    if (this.value == null) return ''
    var text = this.value.split('T')[0].split('-').reverse().join('.')
    this.text = text
    return text // return this.text ends in Maximum call stack size exceeded
  }
})

Solution

  • You need to make the property configurable so that you can delete it:

    var obj = {value: '2018-04-21T12:00:00Z000'};
    
    Object.defineProperty(obj, 'text', {
      get: function () {
        delete this.text
    
        if (this.value == null) return ''
        var text = this.value.split('T')[0].split('-').reverse().join('.')
        console.log("updating")
        this.text = text
        return text
      },
      configurable: true
    //^^^^^^^^^^^^^^^^^^
    });
    console.log("first access");
    console.log(obj.text);
    console.log("second access");
    console.log(obj.text);


    Apart from that, if you are having issues with properties inherited from a prototype object, you cannot delete it but need to use defineProperty to shadow it.