[英]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);
這些大致是采取的方法:
JSON.stringify()
/ JSON.parse()
進行自定義轉換JSON.stringify()
/ JSON.parse()
帶有replacer/reviver參數當然,有可能采用一種混合其中少數幾種的方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.