属性装饰器
基本语法
ts
/**
* 参数说明
* @param target 对于静态属性来说值是类, 对于实例属性来说值是类的原型对象
* @param propertyKey 属性名
*/
function Demo(target: object, propertyKey: string) {
console.log(target, propertyKey) // {} 'name'
}
class Person {
// 静态属性
@Demo static school: string
// 实例属性
@Demo name: string
@Demo age: number
constructor(name: string, age: number) {
this.name = name
this.age = age
}
speak() {
console.log('Halo')
}
}
关于属性遮蔽
如下代码中, 当构造器中的this.age = age
试图再实例上赋值时, 实际上是调用了原型上的age
属性的set
方法
ts
class Person {
name: string
age: number
constructor(name: string, age: number) {
this.name = name
this.age = age
}
}
let value = 99
// 使用 Object.defineProperty 给 Person 原型添加 age 属性, 并配置对应的 get 和 set 方法
Object.defineProperty(Person.prototype, 'age', {
get() {
return value
},
set(v) {
value = v
},
})
const man = new Person('张三', 16)
console.log(man)
应用示例
需求: 定义一个
State
属性装饰器, 监听属性的修改
ts
function State(target: object, propertyKey: string) {
// let value: any
let key = `__${propertyKey}`
Object.defineProperty(target, propertyKey, {
get() {
// return value
return this[key]
},
set(v) {
console.log(`${propertyKey}的最新值是: ${v}`)
this[key] = v
// value = v
},
enumerable: true, // 可枚举性
configurable: true // 可配置性
})
}
class Person {
name: string
@State age: number
constructor(name: string, age: number) {
this.name = name
this.age = age
}
}
const man1 = new Person('张三', 18)
const man2 = new Person('李四', 20)
man1.age = 30
man2.age = 40
// console.log(man1.age, man2.age) // 40, 40
console.log(man1.age, man2.age) // 30, 40