共计 1258 个字符,预计需要花费 4 分钟才能阅读完成。
官网链接
语法
type PropertyDecorator =
(target: Object, propertyKey: string | symbol) => void;
target:间接写在类的属性上?
看个例子:
function capitalizeFirstLetter(str: string) {return str.charAt(0).toUpperCase() + str.slice(1);
}
function observable(target: any, key: string): any {
// prop -> onPropChange
const targetKey = "on" + capitalizeFirstLetter(key) + "Change";
target[targetKey] =
function (fn: (prev: any, next: any) => void) {let prev = this[key];
Reflect.defineProperty(this, key, {set(next) {fn(prev, next);
prev = next;
}
})
};
}
class C {
@observable
foo = -1;
@observable
bar = "bar";
}
const c = new C();
c.onFooChange((prev, next) => console.log(`prev: ${prev}, next: ${next}`))
c.onBarChange((prev, next) => console.log(`prev: ${prev}, next: ${next}`))
c.foo = 100; // -> prev: -1, next: 100
c.foo = -3.14; // -> prev: 100, next: -3.14
c.bar = "baz"; // -> prev: bar, next: baz
c.bar = "sing"; // -> prev: baz, next: sing
编译通不过:
一种解决办法是,增加下图这种 dummy 办法,这种办法不举荐,因为不足灵活性:
另一种办法较通用,即为类增加通用的所谓的 index signature:
语法如下:
意思是类 C 能够领有任意的属性,且属性名称为 string
运行时,target 的类型为类 C 的构造函数:
key 为属性名:
在下图第 15 行代码,间接给 C 的构造函数注入一个新的 on 监听函数:
这个监听函数的函数体,直到代码 44 行 onXXX 被调用时才会被执行:
给 C 对象实例的 foo 属性应用 Reflect.defineProperty API 设置一个 set 办法。
这样,每次该实例的 foo 属性被批改时,就触发其 set 函数:
在 set 函数实现体内,首先调用利用开发人员传入的 回调函数 fn,而后将 this[key] 设置为新的值 next.
运行时,c.foo = 100, 会导致 Reflect.defineProperty 注册在 foo 属性的 set 办法被触发:
在 set 函数里,咱们再也不能拜访到 C 实例的 foo 或者 bar 属性,然而通过闭包,能拜访到其批改之前的原始值:
更多 Jerry 的原创文章,尽在:” 汪子熙 ”:
正文完
发表至: typescript
2021-07-01