我想和装饰者玩耍。
作为第一个目标,我正在尝试为要使用简单的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
成为静态的,因为internalValue
跨SimpleClass
的实例使用。仔细观察它,很明显为什么会这样。但是我不知道该怎么办。
JSFiddle在这里:https://jsfiddle.net/e5sfmbv3/1/