javascript - Varför försvinner min egendom efter Object.defineProperty i dekoratorn?
Jag har en dekoratör som omvandlar ett strängnummer till ett JavaScript-nummer.
Exempel: "87" -> 87.
Koden är ganska enkel:
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' }
Varför visas inte id-fältet i den andra console.log och hur kan jag få det att visas? Jag kan komma åt det men det är dolt i konsolen.
Tack!
Svar #1
Eftersom en egenskapsdekoration för en instans-egenskap tillämpas på prototypen av klassen, inte på någon instans. Det är det bästa du kan göra eftersom ingen instans av User existerar innan du anropar new User(). När du bara använder console.log() för att få debugutdata ser du bara instansens egna egenskaper, inte de som finns på prototypen.
Eftersom alla instanser delar en prototyp, vill du förmodligen inte göra på detta sätt:
let user = new User({
id: '712',
isActive: '1'
})
let user2 = new User({
id: '567',
isActive: '1'
})
console.log(user.id) // 567!
En prototyp, ett id-värde för hela klassen. Alla User-objekt har samma id. Oj då.
Du vill förmodligen åtminstone göra något med instanser när de är tillgängliga:
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,
});
}
Observera användningen av this inuti get- och set-metoderna. Det placerar _val-egenskapen på instansen, så du kommer att få olika sådana. Du kommer fortfarande inte att se id via console.log(), (och du kommer att se _val).
Det finns för många sätt att konfigurera objektet så att det skriver ut vad du förväntar dig med console.log() och beter sig som du förväntar dig (en id per instans) för att jag ska kunna räkna upp dem här. Ett tips: du kan sätta egenskapsåtkomstmetoden på instansen genom att ändra klasskonstruktorn istället för att försöka använda en dekoratör. Och se till att den tillagda _val inte är uppräkningsbar så att den inte syns. Hoppas det hjälper; lycka till!
