如果您为任何class 对象实现自己的toJSON() 函数,那么只需普通的旧JSON.stringify() 即可工作!
Maps 和 Arrays 的键? Maps 与其他 Map 作为值? Map 在常规 Object 内?甚至可能是您自己的自定义类;容易。
Map.prototype.toJSON = function() {
return Array.from(this.entries());
};
就是这样!
这里需要原型操作。您可以手动将 toJSON() 添加到所有非标准内容中,但实际上您只是在避免 JS 的强大功能
DEMO
test = {
regular : 'object',
map : new Map([
[['array', 'key'], 7],
['stringKey' , new Map([
['innerMap' , 'supported'],
['anotherValue', 8]
])]
])
};
console.log(JSON.stringify(test));
输出:
{"regular":"object","map":[[["array","key"],7],["stringKey",[["innerMap","supported"],["anotherValue",8]]]]}
不过,反序列化一直到真正的Maps 并不是那么自动。使用上面的结果字符串,我将重新制作地图以提取一个值:
test2 = JSON.parse(JSON.stringify(test));
console.log((new Map((new Map(test2.map)).get('stringKey'))).get('innerMap'));
输出
"supported"
这有点乱,但是用一点magic sauce 你也可以使反序列化自动化。
Map.prototype.toJSON = function() {
return ['window.Map', Array.from(this.entries())];
};
Map.fromJSON = function(key, value) {
return (value instanceof Array && value[0] == 'window.Map') ?
new Map(value[1]) :
value
;
};
现在 JSON 是
{"regular":"object","test":["window.Map",[[["array","key"],7],["stringKey",["window.Map",[["innerMap","supported"],["anotherValue",8]]]]]]}
使用我们的Map.fromJSON,反序列化和使用非常简单
test2 = JSON.parse(JSON.stringify(test), Map.fromJSON);
console.log(test2.map.get('stringKey').get('innerMap'));
输出(没有使用new Map()s)
"supported"
DEMO