带有getter和setter的属性装饰器

时间:2020-03-21 07:58:15

标签: javascript decorator

我想和装饰者玩耍。

作为第一个目标,我正在尝试为要使用简单的getter和setter的属性创建一个简单的装饰器。

这是我当前的代码:

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成为静态的,因为internalValueSimpleClass的实例使用。仔细观察它,很明显为什么会这样。但是我不知道该怎么办。

JSFiddle在这里:https://jsfiddle.net/e5sfmbv3/1/

0 个答案:

没有答案