为什么我的 属性 在装饰器中的 Object.defineProperty 之后消失了?
Why does my property disapear after Object.defineProperty in decorator?
我有一个装饰器,可以将字符串数字转换为 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 中,我怎样才能让它出现?
我可以访问它,但它隐藏在控制台中。
谢谢!
因为 property decorator for an instance property is applied to the prototype of the class, not to any instance. That is the best you can do because no instance of User
exists before you call new User()
. When you just use console.log()
to get debug output you only see the instance's own 属性,而不是原型上的属性。
由于所有实例共享一个原型,您可能不想这样做:
let user = new User({
id: '712',
isActive: '1'
})
let user2 = new User({
id: '567',
isActive: '1'
})
console.log(user.id) // 567!
一个原型,一个id
值,整个class。所有 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,
});
}
注意在 get
和 set
方法中使用了 this
。这会将 _val
属性 放在实例上,因此您将获得不同的实例。您仍然不会通过 console.log()
看到 id
(而您 将 看到 _val
)。
有太多方法可以配置对象,以便它打印出您对 console.log()
的期望,并按您期望的方式运行(每个实例一个 id
),我在此一一列举。作为一个提示:您可以通过修改 class 构造函数而不是尝试使用装饰器来将 属性 访问器放在实例上。并确保添加的 _val
不可枚举,因此它不会出现。希望有所帮助;祝你好运!
我有一个装饰器,可以将字符串数字转换为 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 中,我怎样才能让它出现? 我可以访问它,但它隐藏在控制台中。
谢谢!
因为 property decorator for an instance property is applied to the prototype of the class, not to any instance. That is the best you can do because no instance of User
exists before you call new User()
. When you just use console.log()
to get debug output you only see the instance's own 属性,而不是原型上的属性。
由于所有实例共享一个原型,您可能不想这样做:
let user = new User({
id: '712',
isActive: '1'
})
let user2 = new User({
id: '567',
isActive: '1'
})
console.log(user.id) // 567!
一个原型,一个id
值,整个class。所有 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,
});
}
注意在 get
和 set
方法中使用了 this
。这会将 _val
属性 放在实例上,因此您将获得不同的实例。您仍然不会通过 console.log()
看到 id
(而您 将 看到 _val
)。
有太多方法可以配置对象,以便它打印出您对 console.log()
的期望,并按您期望的方式运行(每个实例一个 id
),我在此一一列举。作为一个提示:您可以通过修改 class 构造函数而不是尝试使用装饰器来将 属性 访问器放在实例上。并确保添加的 _val
不可枚举,因此它不会出现。希望有所帮助;祝你好运!