如何将JavaScript类实例属性转换为普通JS对象?
类实例转普通JS对象的通用最优方案
问题场景
我有一个类实例,示例代码如下:
class MyObject{ id: number = 0; data: string = ""; constructor(){ } toString(){ return `${this.id}: ${this.data}`; } } const myObj = new MyObject() myObj.data = "hello"
需要将其转换为普通JS对象:
const output = {id: 10, data: "hello"}
已知JSON.parse(JSON.stringify(myObj))可行,但不想用序列化的方式,需要通用解决方案,而非针对特定类写toObject()这类硬编码属性的实现。
通用实现方案
方案1:展开语法或Object.assign()
这是最简洁的实现方式,直接把实例的自身可枚举属性复制到空对象中,自动过滤原型链上的方法(比如toString):
// 展开语法 const output = {...myObj}; // 或者Object.assign const output = Object.assign({}, myObj);
两种写法效果完全一致,输出结果为{ id: 0, data: "hello" },完美符合需求。
方案2:自定义遍历(更灵活)
如果需要处理Symbol类型的属性,或者要过滤某些属性,可以手动遍历实例的所有自身属性:
function convertInstanceToPlain(instance) { const result = {}; // 处理字符串键的属性 Object.getOwnPropertyNames(instance).forEach(key => { result[key] = instance[key]; }); // 处理Symbol键的属性(如果需要) Object.getOwnPropertySymbols(instance).forEach(sym => { result[sym] = instance[sym]; }); return result; } // 使用示例 const output = convertInstanceToPlain(myObj);
方案对比
- 展开语法/Object.assign:写法极简,性能优秀,覆盖绝大多数日常场景,只处理字符串键的可枚举属性。
- 自定义遍历:灵活性更高,可扩展处理Symbol属性、过滤特定属性等场景。
这两种方案都不需要序列化,避免了JSON.parse(JSON.stringify())的诸多问题——比如无法处理函数、循环引用、Date对象会被转成字符串等,性能也更优。
内容的提问来源于stack exchange,提问作者El Hocko
相关产品推荐
相关产品推荐

