JSON.stringify
будет только перебирать собственные перечисляемые свойства. Здесь, так как layout
является свойством объекта прототипа , а не самого экземпляра, когда вы пытаетесь структурировать экземпляр, метод получения не вызывается. (но поскольку _layout
является собственным перечисляемым свойством, оно означает , включенное в результат)
Аналогично, следующий строковый объект пуст:
const obj = Object.create({
get prop() {
return 'val';
}
});
console.log(JSON.stringify(obj));
Вы можете исправить это, поместив геттер непосредственно в экземпляр и сделав _layout
не перечисляемым. Таким образом, при строковом преобразовании будет вызван метод получения, но _layout
не будет включен:
export class KitSection {
uid: string;
order: number;
private _layout: KitLayout;
constructor(init?: Partial<KitSection>) {
Object.defineProperty(
this,
'layout',
{
enumerable: true,
get() {
return this._layout;
},
set(newVal) {
this._layout = new KitLayout(newVal);
}
}
);
Object.defineProperty(
this,
'_layout',
{
enumerable: false,
value: undefined,
}
);
Object.assign(this, init);
}
}
const section = new KitSection(data);
Это будет выглядеть немного яснее, если вместо этого вы используете синтаксис поля частного класса:
export class KitSection {
#layout: KitLayout | undefined;
constructor(init?: Partial<KitSection>) {
Object.defineProperty(
this,
'layout',
{
enumerable: true,
get() {
return this.#layout;
},
set: (newVal) => {
this.#layout = new KitLayout(newVal);
}
}
);
Object.assign(this, init);
}
}
Вы также можете вызвать геттер вручную.
Если KitLayout
по существу сериализуем, чтобы превратить сериализованный объект обратно в экземпляр KitSection, KitLayout
или один из его вспомогательных методов должен быть в состоянии превратить сериализованный KitLayout
в экземпляр. Либо снова передайте его через конструктор (просто вызовите new KitSection
, который передает его KitLayout
), либо отделите layout
от десериализованного объекта и используйте отдельный метод для KitSection
, который вызывает помощник KitLayout
Метод и присваивает приватное свойство, может быть что-то вроде:
integrateLayout(layoutInfo) {
this.#layout = KitLayout.makeKitLayoutFromLayoutInfo(layoutInfo)
}
, где layoutInfo
- простой объект.