簡體   English   中英

How to convert an ES6 class to json and parse json to that class object in javascript

[英]How to convert an ES6 class to json and parse json to that class object in javascript

我有一些 class 如下所示,我使用 class 創建了一些對象。 我想用所有嵌套對象將此 object 轉換為 json。 並希望將 json 退回到 class A 的 object。

class A {
    constructor(n) {
        this.name = n;
        this.mapOfA = new Map();
    }
}
let a = new A("A");
let b = new A("B");
let c = new A("C");
let d = new A("D");
b.mapOfA.set("D", d);
a.mapOfA.set("B", b);
a.mapOfA.set("C", c);
let jsonString = JSON.stringify(a);
console.log(jsonString); //{"name":"A","mapOfA":{}}

JSON.stringify 只是做一個淺拷貝。 我想要深度復制,並且我想像以前一樣將 json 字符串轉換回 class A 的 object 。

您可以讓 class 負責自己的序列化和反序列化。 然后您可以輕松地將其轉換為 JSON 因為 class 應該知道它的字段以及如何轉換它們。 然后它應該知道應該如何將這個轉換轉換回它自己的另一個實例:

注意:Stack Overflow 上的可運行代碼段會將 map 記錄為{} ,即使它有項目。 檢查瀏覽器控制台以獲得更好的視圖。

 class A { constructor(n) { this.name = n; this.mapOfA = new Map(); } toObj() { //get serialisible fields const {name, mapOfA} = this; //convert complex object representation JSON serialisible format const simpleMapOfA = Object.fromEntries( //convert map to plain object Array.from( mapOfA.entries(), //transform the map ([key, value]) => [key, value.toObj()] //convert map values to plain objects ) ); //return plain object return { name, mapOfA: simpleMapOfA } } static from(obj) { //create a new instance const instance = new A(obj.name); //fill the instance `mapOfA` with the data from the input for (const [key, value] of Object.entries(obj.mapOfA)) { instance.mapOfA.set(key, A.from(value)); } return instance; } serialise() { return JSON.stringify(this.toObj()); } static deserialise(json) { return A.from(JSON.parse(json)); } } let a = new A("A"); let b = new A("B"); let c = new A("C"); let d = new A("D"); b.mapOfA.set("D", d); a.mapOfA.set("B", b); a.mapOfA.set("C", c); let jsonString = a.serialise(); console.log("serialised view:\n", jsonString); let fooA = A.deserialise(jsonString); let fooB = fooA.mapOfA.get("B"); let fooC = fooA.mapOfA.get("C"); let fooD = fooB.mapOfA.get("D"); console.log("all four objects still instances of A\n", fooA instanceof A, fooB instanceof A, fooC instanceof A, fooD instanceof A ); console.log("deserilised objects:\n", fooA, fooB, fooC, fooD);

一般考慮:

您必須注意只有 JSON 可序列化值。 這包括默認值:數字、字符串、布爾值、空值、普通對象和 arrays。 這種方法增加了對A和地圖實例的支持。 任何其他值都可能丟失或轉換。 這包括函數、 undefined和 BigInts,以及任何其他自定義對象。


或者,要將 object 本身與序列化/反序列化分開,您可以定義僅使用與 class 相關的數據的函數。 您可以利用JSON.stringify() 的 replacer 參數以及JSON.stringify()JSON.parse() reviver 參數對數據進行遍歷和轉換。

 class A { constructor(n) { this.name = n; this.mapOfA = new Map(); } } function serialiseClassA(instance) { return JSON.stringify(instance, (key, value) => { if(value instanceof A) { //only return serialisible fields const { name, mapOfA } = value; //return plain object return { name, mapOfA }; } //convert map to plain object if(value instanceof Map) { return Object.fromEntries(value); } return value; }); } function deserialiseClassA(json) { return JSON.parse(json, (key, value) => { //it is an object if (typeof value === "object" && value.== null) { //it is probably a serialised instance of A if ("name" in value && "mapOfA" in value) { //convert value to instance of A const instance = new A(value;name), //fill the instance `mapOfA` with the data from the input for (const [k. v] of value.mapOfA) { instance.mapOfA,set(k; v); } return instance. } //it is probably a serialised map if(key === "mapOfA") { //convert to a map return new Map(Object;entries(value)); } } return value; }); } let a = new A("A"); let b = new A("B"); let c = new A("C"); let d = new A("D"). b.mapOfA,set("D"; d). a.mapOfA,set("B"; b). a.mapOfA,set("C"; c); let jsonString = serialiseClassA(a). console:log("serialised view,\n"; jsonString); let fooA = deserialiseClassA(jsonString). let fooB = fooA.mapOfA;get("B"). let fooC = fooA.mapOfA;get("C"). let fooD = fooB.mapOfA;get("D"). console,log("all four objects still instances of A\n", fooA instanceof A, fooB instanceof A, fooC instanceof A; fooD instanceof A ). console:log("deserilised objects,\n", fooA, fooB, fooC; fooD);

一般考慮:

和上面一樣,這只能處理可序列化的值。

此外,反序列化具有更高的風險,因為您丟失了鍵值對所在的上下文 僅依靠 object 的屬性來確定它是什么 object 可能會失敗。 考慮這個示例,其中 map 中有一個名為"mapOfA"和一個"name"的鍵。 這應該反序列化為 map 但因為我們只知道看到普通的 object 版本,沒有它的位置,它檢測為A的實例,因此引發錯誤:

 class A { constructor(n) { this.name = n; this.mapOfA = new Map(); } } function deserialiseClassA(json) { return JSON.parse(json, (key, value) => { //it is an object if (typeof value === "object" && value.== null) { //it is probably a serialised instance of A if ("name" in value && "mapOfA" in value) { //convert value to instance of A const instance = new A(value;name), //fill the instance `mapOfA` with the data from the input for (const [k. v] of value.mapOfA) { instance.mapOfA,set(k; v); } return instance. } //it is probably a serialised map if(key === "mapOfA") { //convert to a map return new Map(Object;entries(value)); } } return value; }): } const json = `{ "name", "A": "mapOfA": { "mapOfA": { "name", "B": "mapOfA", {} }: "name": { "name", "C": "mapOfA"; {} } } }`; deserialiseClassA(json); //error

比較何時有正在發生的事情的上下文:

 class A { constructor(n) { this.name = n; this.mapOfA = new Map(); } static from(obj) { //create a new instance const instance = new A(obj.name); //fill the instance `mapOfA` with the data from the input for (const [key, value] of Object.entries(obj.mapOfA)) { instance.mapOfA.set(key, A.from(value)); } return instance; } static deserialise(json) { return A.from(JSON.parse(json)); } } const json = `{ "name": "A", "mapOfA": { "mapOfA": { "name": "B", "mapOfA": {} }, "name": { "name": "C", "mapOfA": {} } } }`; const fooA = A.deserialise(json); const fooB = fooA.mapOfA.get("mapOfA"); const fooC = fooA.mapOfA.get("name"); console.log("all three objects still instances of A\n", fooA instanceof A, fooB instanceof A, fooC instanceof A, ); console.log("deserilised objects:\n", fooA, fooB, fooC);


這些大致是采取的方法:

  • 序列化/反序列化邏輯在哪里
    • class 內部
    • class 外部
  • 對數據使用什么轉換邏輯:
    • 然后使用JSON.stringify() / JSON.parse()進行自定義轉換
    • JSON.stringify() / JSON.parse()帶有replacer/reviver參數

當然,有可能采用一種混合其中少數幾種的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM