Декоратор недвижимости с геттером и сеттером - PullRequest
0 голосов
/ 21 марта 2020

Я хочу поиграть с декораторами.

В качестве первой цели я пытаюсь создать простой декоратор для свойства, в котором я хочу иметь простые геттеры и сеттеры.

Здесь мой текущий код:

function fooddecorator(target, key, descriptor) {
  const {
    configurable,
    enumerable,
    value,
    initializer,
  } = descriptor

  const initialValue = initializer ? initializer.call(this) : value

  return {
    configurable,
    enumerable,

    set(newValue) {
      console.log("SETTER CALLED: ", newValue)

      Object.defineProperty(this, key, {
        configurable,
        enumerable,
        writable: true,
        value: newValue,
      })

      return newValue
    },

    get() {
      console.log("GETTER CALLED")
      return initialValue
    },
  }
}

class SimpleClass {
  @fooddecorator
  food = "Pizza"
}

const sc = new SimpleClass()
console.log("sc.food 1: ", sc.food)
sc.food = "Burgers"
console.log("sc.food 2: ", sc.food)
sc.food = "Steak"
console.log("sc.food 3: ", sc.food)

const sc2 = new SimpleClass()
console.log("sc2.food 1: ", sc2.food)
sc2.food = "Pasta"
console.log("sc2.food 2: ", sc2.food)
sc2.food = "Cola"
console.log("sc2.food 3: ", sc2.food)
console.log("sc.food 4: ", sc.food)

Вывод:

GETTER CALLED
sc.food 1:  Pizza
SETTER CALLED:  Burgers
sc.food 2:  Burgers
sc.food 3:  Steak
GETTER CALLED
sc2.food 1:  Pizza
SETTER CALLED:  Pasta
sc2.food 2:  Pasta
sc2.food 3:  Cola
sc.food 4:  Steak

Проблемы:

1.) Как только set() вызывается в первый раз, он явно перезаписывает свойство this.key со своим собственным дескриптором свойства. Это приводит к перезаписи get() и set().

Проблема заключается в том, что я не нашел другого решения для назначения нового значения (= newValue) свойству. Например, это дает сбой с "превышен размер стека ..." - ошибка рекурсии:

set(newValue) {
  this[key] = newValue
}

2.) get() в настоящее время возвращает только initialValue. Я не нашел способ вернуть начальное значение при первом доступе, а затем вернуть впоследствии установленные значения. Это параллельная проблема с моей предыдущей проблемой, потому что я также получаю ошибку рекурсии, если я делаю это:

get() {
  return this[key]
}

Я уверен, что понимаю что-то очень фундаментальное, но простое неправильно. Я просто понятия не имею, что это может быть.

То, что я тоже пробовал:

Я также пытался создать «скрытую» переменную, которой я присваиваю значения:

function fooddecorator(target, key, descriptor) {
  ...
  let internalValue = initialValue

  return {
    configurable,
    enumerable,

    set(newValue) {
      internalValue = newValue
    },

    get() {
      return internalValue
    }
  }
}

Сначала я думал, что это сработало. Но в основном это свойство food stati c, потому что internalValue используется во всех случаях SimpleClass. Если присмотреться к этому, становится очевидным, почему это так. Однако я понятия не имею, что с этим делать.

JSFiddle здесь: https://jsfiddle.net/e5sfmbv3/1/

...