javascript 类实例属性到普通对象

问题描述 投票:0回答:2

我有一个类的实例,比如说

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"}

我知道这行得通,但必须有一种方法可以不序列化整个对象:

const output = JSON.parse(JSON.stringify(myObj))

最好的方法是什么?

请注意,我正在寻找一个通用的解决方案,而不是像这样:

toObject() {
    return {
      id: this.id,
      data: this.data,
    };
  }
javascript json typescript
2个回答
0
投票

要创建仅具有实例属性而不具有实例方法的对象,您可以使用

Object.assign()
将对象的所有可枚举 own 属性复制到另一个对象,该对象可以指定为新的普通对象。

class MyObject{
    id = 0;
    data = "";

    constructor(){
    }

    toString(){
        return `${this.id}: ${this.data}`;
    }

    
}

const instance = new MyObject();
const properties = Object.assign({}, instance);
console.log(properties);


0
投票

对于简单的情况,您可以使用object literal spread syntax

class MyObject{
    constructor(){
        this.id = 0;
        this.data = "";
    }
    toString(){
        return `${this.id}: ${this.data}`;
    }
}

const myObj = new MyObject();
console.log(myObj.constructor.name); // MyObject
myObj.data = "hello";
const result = {...myObj};
console.log(result.constructor.name); // Object

如果您的原始对象具有嵌套的自定义对象——也需要转换为普通对象或数组——那么要么创建一个递归函数,要么使用

structuredClone
函数(添加于 ECMAScript 2023Node 17) .这是一个更真实的链表实现示例:

class Node {
    constructor(value, next) {
        this.value = value;
        this.next = next;
    }
    *[Symbol.iterator]() {
        yield this.value;
        if (this.next) yield* this.next;
    }
}

class LinkedList {
    constructor(...values) {
        this.head = null;
        for (const value of values.toReversed()) {
            this.head = new Node(value, this.head);
        }
    }
    *[Symbol.iterator]() {
        if (this.head) yield* this.head
    }
    toString() {
        return [...this].join("→");
    }
}

const myObj = new LinkedList(1, 2, 3);
console.log("list: ", myObj.constructor.name, myObj.toString());
const result = structuredClone(myObj);
console.log("list2: ", result.constructor.name, myObj);

但是请注意,这确实在幕后对整个对象进行序列化/反序列化,并且在涉及本地类的地方,它们也在目标对象中维护(如

Set
Map
Date
RegExp
Number
,...)。这可能是也可能不是你想要的,但要意识到
JSON.stringify
在这种情况下也有 particular 结果:对于
Set
Map
RegExp
你得到一个空对象,对于
Date
你得到一个字符串,...等,所以这可能需要特别注意——取决于期望。

© www.soinside.com 2019 - 2024. All rights reserved.