我有一个装饰器,可以将一个字符串编号转换为javascript编号。
示例:"87"
- > 87
。
代码非常简单:
function digit(target: any, key: string) {
// property value
var _val = this[key];
// property getter
var getter = () => _val;
// property setter
var setter = (newVal) => _val = parseInt(newVal)
// Create new property with getter and setter
Object.defineProperty(target, key, {
get: getter,
set: setter,
enumerable: true,
configurable: true,
});
}
class User {
@digit
public id: number;
public isActive: boolean;
constructor(instanceData) {
this.id = instanceData.id;
this.isActive = instanceData.isActive;
}
}
let user = new User({
id: '712',
isActive: '1'
})
console.log([user.id]) // [ 712 ] as expected
console.log(user) // Person { isActive: '1' }
为什么id字段没有出现在第二个console.log中,如何显示? 我可以访问它,但它隐藏在控制台中。
谢谢!
答案 0 :(得分:0)
因为实例属性的property decorator应用于类的原型,而不是任何实例。这是您可以做的最好的事情,因为在致电User
之前,不存在new User()
的实例。当您只使用console.log()
获取调试输出时,您只能看到实例的own属性,而不是原型上的属性。
由于所有实例共享原型,您可能不希望这样做:
let user = new User({
id: '712',
isActive: '1'
})
let user2 = new User({
id: '567',
isActive: '1'
})
console.log(user.id) // 567!
一个原型,整个类的一个id
值。所有User
个对象都具有相同的id
。糟糕。
您可能希望至少在实例可用时执行某些操作:
function digit(target: any, key: string) {
// Create new property with getter and setter
Object.defineProperty(target, key, {
get: function () { return this._val },
set: function (newVal) { this._val = parseInt(newVal) },
enumerable: true,
configurable: true,
});
}
请注意在this
和get
方法中使用set
。这会将_val
属性放在实例上,因此您将获得不同的属性。您仍然无法通过id
看到console.log()
,(将看到_val
)。
有太多方法可以配置对象,以便打印出您对console.log()
的期望,并按照您期望的方式运行(每个实例一个id
),以便我在此枚举。作为一个提示:您可以通过修改类构造函数而不是尝试使用装饰器来将属性访问器放在实例上。并确保添加的_val
不可枚举,因此不会显示。希望有所帮助;祝你好运!