javascript - 以编程方式添加和删除智能getter

时间:2018-04-24 15:07:45

标签: javascript getter defineproperty

我尝试以编程方式添加和删除(用于缓存目的)来自对象的getter。我正在添加一个这样的吸气剂:

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

obj.text只应在首次访问时进行评估,并为后续调用缓存计算值。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get展示了如何实现这样的智能getter:

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

但我无法在delete this.text函数中使用getter。我发现的是,this是Object的原型而不是实例 - 是正确的吗?如果是这样,我如何删除实例的getter并将其替换为计算值?

编辑:

根据评论,getter和object看起来像这样:

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
  }
})

2 个答案:

答案 0 :(得分:3)

您需要使属性可配置,以便您可以将其删除:



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);




除此之外,如果您遇到从原型对象继承的属性的问题,那么cannot delete it but need to use defineProperty to shadow it

答案 1 :(得分:2)

  

我发现的是,这是对象的原型而不是实例......

不在您已展示的代码中,除非您奇怪地称之为。

一种方法是使用Object.defineProperty重新定义属性。

例如,如果您在一次性对象上执行此操作:



var obj = {
  get notifier() {
    var value = Math.random();
    console.log("Getter called");
    Object.defineProperty(this, "notifier", {
      value: value
    });
    return value;
  }
};
console.log("First use");
console.log(obj.notifier);
console.log("Second use");
console.log(obj.notifier);




或者如果它不是一次性的:



function Maker() {
}
Object.defineProperty(Maker.prototype, "notifier", {
  get: function() {
    var value = Math.random();
    console.log("Getter called");
    Object.defineProperty(this, "notifier", {
      value: value
    });
    return value;
  },
  configurable: true
});
var obj = new Maker();
console.log("First use");
console.log(obj.notifier);
console.log("Second use");
console.log(obj.notifier);




由于您似乎没有使用任何ES2015 +功能,因此我坚持使用上述ES5级别的内容。