gpt4 book ai didi

javascript - 如何将带有 getter/setter 的 TypeScript 类实例转换为 JSON 以存储在 MySQL 数据库中

转载 作者:行者123 更新时间:2023-12-05 06:18:43 26 4
gpt4 key购买 nike

我有以下包含 getter/setter 的 TypeScript 类:

export class KitSection {

uid: string;
order: number;

set layout(layout: KitLayout) {
this._layout = new KitLayout(layout);
}

get layout() {
return this._layout;
}

private _layout: KitLayout;

constructor(init?: Partial<KitSection>) {
Object.assign(this, init);
}

}

// I can create an instance like so:
const section = new KitSection(data);

我需要将此实例作为 JSON 对象POST 到我的服务器,以存储在类型为 JSON 的 MySQL 数据库列中,所以我想我可以执行以下操作:

const jsonSection = JSON.parse(JSON.stringify(section))

这创建了一个 JSON 对象,但是当我在控制台中检查时,我看到我的私有(private) getter/setter 变量而不是对象中的公共(public)变量:

console.log(jsonSection);

///IN CONSOLE///

uid: "a"
order: 0
_layout: {_rows: Array(2), columns: 12}

我不想在我的数据库中存储私有(private)变量 _layout,我需要存储在 getter/setter 中定义的公共(public)变量:layout

接下来,我查看了此处提供的答案:https://stackoverflow.com/a/44237286/6480913它建议添加以下方法以转换为 JSON:

public toJSON(): string {
let obj = Object.assign(this);
let keys = Object.keys(this.constructor.prototype);
obj.toJSON = undefined;
return JSON.stringify(obj, keys);
}

但是,这会返回一个空对象。经检查,当我 console.log() this.constructor.prototype 时,我看到了对象的所有属性,但每个对象都是灰色的,所以当我们使用 Object.keys() 时,我收到一个空数组。为什么这些构造函数属性是灰色的?

最佳答案

JSON.stringify 迭代自己的可枚举属性。在这里,由于 layoutprototype 对象的属性,而不是实例本身,当您尝试对实例进行字符串化时,不会调用 getter。 (但由于_layout 自己的可枚举属性,它包含在结果中)

类似地,下面的字符串化对象是空的:

const obj = Object.create({
get prop() {
return 'val';
}
});
console.log(JSON.stringify(obj));

您可以通过将 getter 直接放在实例上并使 _layout 不可枚举来修复它。这样,当字符串化时,将调用 getter,但不会包含 _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);

如果改用私有(private)类字段语法,它会看起来更清晰一些:

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);
}
}

您也可以手动调用 getter。

如果 KitLayout 本质上是可序列化的,要将序列化对象变回 KitSection 实例,KitLayout 或其辅助方法之一需要能够将序列化对象KitLayout 到一个实例中。要么再次通过构造函数传递它(只需调用 new KitSection,它将它交给 KitLayout),要么将 layout 与反序列化对象分开,然后在 KitSection 上有一个单独的方法调用 KitLayout 的辅助方法并分配私有(private)属性,可能是这样的:

integrateLayout(layoutInfo) {
this.#layout = KitLayout.makeKitLayoutFromLayoutInfo(layoutInfo)
}

其中 layoutInfo 是普通对象。

关于javascript - 如何将带有 getter/setter 的 TypeScript 类实例转换为 JSON 以存储在 MySQL 数据库中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61166669/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com