如何序列化带有只读属性的JavaScript对象?
问题:如何让JSON.stringify序列化类的getter属性?
以下代码执行后输出{}:
class A { get p1(): number { return 1; } get p2(): number { return 2; } } const a = new A(); console.log(JSON.stringify(a));
有没有办法得到如下输出?
{ "p1": 1, "p2": 2 }
原因
JSON.stringify默认只会序列化对象自身的可枚举数据属性,而类定义中声明的getter属于访问器属性,默认是不可枚举的,因此不会被序列化。
解决方案
方法1:给类添加toJSON方法
手动指定序列化时要返回的对象,这是最直接的方式:
class A { get p1(): number { return 1; } get p2(): number { return 2; } // 自定义序列化逻辑 toJSON() { return { p1: this.p1, p2: this.p2 }; } } const a = new A(); // 第二个参数为null,第三个参数2用于格式化输出 console.log(JSON.stringify(a, null, 2));
方法2:自动收集原型上的getter属性
如果不想手动维护toJSON里的属性列表,可以通过遍历类原型的属性描述符,自动提取所有getter对应的属性值:
class A { get p1(): number { return 1; } get p2(): number { return 2; } } const a = new A(); // 提取原型上所有带getter的属性 const getterKeys = Object.entries(Object.getOwnPropertyDescriptors(A.prototype)) .filter(([_, desc]) => typeof desc.get === 'function') .map(([key]) => key); // 生成包含属性值的对象 const result = Object.fromEntries(getterKeys.map(key => [key, a[key]])); console.log(JSON.stringify(result, null, 2));
方法3:显式将getter设为可枚举
在类的构造函数中使用Object.defineProperty定义getter,并设置enumerable: true,这样JSON.stringify就能自动识别:
class A { constructor() { Object.defineProperty(this, 'p1', { get: () => 1, enumerable: true // 标记为可枚举 }); Object.defineProperty(this, 'p2', { get: () => 2, enumerable: true }); } } const a = new A(); console.log(JSON.stringify(a, null, 2));
内容的提问来源于stack exchange,提问作者Jesús López
相关产品推荐
相关产品推荐

