我想将一些复杂的JavaScript对象转换为JSON(例如,在将数据保存到文件之前)。这些对象可以包含任意类型的任意嵌套数据值,包括ES6 / ES2015映射和/或集合。 e.g。
const myOriginalObject = {
a: [1, new Set([2, new Map()]), 3],
c: {d: new Map([['e', 4], ['f', new Set()]])}
};
但是,JSON.stringify
会导致地图/集数据丢失。那么,有没有一种方法可以在存储为JSON时在地图和集合中维护数据?
答案 0 :(得分:0)
您可以将replacer
函数与JSON.stringify
和reviver
函数一起使用JSON.parse
,将地图和/或集合转换为标准JavaScript数组,然后再将其转换回来。 e.g。
替换和启动功能:
const replacer = (k, v) =>
v instanceof Map ? ({_WAS_MAP: [...v]}) :
v instanceof Set ? ({_WAS_SET: [...v]}) : v;
const reviver = (k, v) =>
v && v._WAS_MAP ? new Map(v._WAS_MAP) :
v && v._WAS_SET ? new Set(v._WAS_SET) : v;
此技术使用例如JSON.stringify
内的a map-to-array conversion strategy,同时将新数组“标记”为已从地图中导出,例如它会将Map { 'a' => 1 }
转换为{"_WAS_MAP":[["a",1]]}
。然后,稍后,JSON.parse
可以查找标记为_WAS_MAP
的属性,并知道将这些属性转换回地图。类似的策略可以用于集合。
示例代码:
const myOriginalObject = {
a: [1, new Set([2, new Map()]), 3],
c: {d: new Map([['e', 4], ['f', new Set()]])}
};
console.log('original:', myOriginalObject);
const mySavedJson = JSON.stringify(myOriginalObject, replacer);
console.log('JSON:', mySavedJson);
const myRetrievedObject = JSON.parse(mySavedJson, reviver);
console.log('retrieved:', myRetrievedObject); // all data is recovered
输出(为清晰起见编辑了空格):
original: { a :[1, Set {2, Map {} },3], c :{ d: Map { 'e' => 4, 'f' => Set {} }}}
JSON: {"a":[1,{"_WAS_SET":[2,{"_WAS_MAP":[]}]},3],"c":{"d":{"_WAS_MAP":[["e", 4],["f",{"_WAS_SET":[]}]]}}}
retrieved: { a :[1, Set {2, Map {} },3], c :{ d: Map { 'e' => 4, 'f' => Set {} }}}
(我没有将上述代码包含在正常工作的代码段中,因为console.log
显示地图并在运行时如上所述设置数据,例如,节点,它在运行时不会显示StackOverflow上的代码片段。)