javascript - программно добавляйте и удаляйте смарт-геттер - PullRequest
0 голосов
/ 24 апреля 2018

Я пытаюсь программно добавлять и удалять (для целей кэширования) геттеры из объекта. Я добавляю геттер как это:

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

obj.text следует оценивать только при первом обращении к нему, а вычисленное значение кэшируется для последующих вызовов.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get показывает, как реализовать интеллектуальный метод получения, подобный этому:

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

Я не могу использовать delete this.text внутри моей функции getter. Я обнаружил, что 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
  }
})

Ответы [ 2 ]

0 голосов
/ 24 апреля 2018

Вам нужно сделать свойство настраиваемым, чтобы вы могли удалить его:

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

Кроме того, если у вас есть проблемы со свойствами, унаследованными от объекта-прототипа, вы не можете удалить его, но вам нужно использовать defineProperty длятень это .

0 голосов
/ 24 апреля 2018

Я обнаружил, что это прототип Объекта, а не экземпляр ...

Ни в том коде, который вы показали, ни в том случае, если вы не 'Вызываете его странным образом.

Один из способов сделать это - использовать 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);

Я придерживался описанного выше уровня ES5, поскольку вы, похоже, не использовали какие-либо функции ES2015 +.

...