我想开始使用ES6地图而不是JS对象,但我被阻止了,因为我不知道如何JSON.stringify()一个地图。我的键保证是字符串,我的值总是会被列出。我真的必须写一个包装器方法来序列化吗?
当前回答
非常简单的方法。
const map = new Map();
map.set('Key1', "Value1");
map.set('Key2', "Value2");
console.log(Object.fromEntries(map));
` 输出:
{"Key1": "Value1","Key2": "Value2"}
其他回答
你不能。
映射的键可以是任何东西,包括对象。但是JSON语法只允许字符串作为键。所以一般情况下是不可能的。
我的键肯定是字符串,我的值总是列表
在这种情况下,您可以使用普通对象。它将有以下优势:
它可以被字符串化为JSON。 它可以在旧的浏览器上运行。 这样可能会更快。
不能调用JSON。在Map或Set上进行stringify。
您将需要转换:
使用Object. fromentries或 使用展开运算符[…]
在调用JSON.stringify之前
Map
常量 obj = {'Key1': 'Value1', 'Key2': 'Value2'}, map = new map (Object.entries(obj)); 地图。设置(“Key3”、“Value3”);//添加一个新条目 //不显示键值对 console.log(地图:,JSON.stringify(地图)); //显示键值对 console.log(JSON.stringify(Object.fromEntries(map), null, 2)); .as-console-wrapper {top: 0;Max-height: 100%重要;}
Set
常量 arr = ['Value1', 'Value2'], set = new set (arr); set.add(“Value3”);//添加一个新项目 //不显示值 console.log (': ', JSON.stringify(集)); //显示值 console.log (JSON.stringify([…Set], null, 2)); .as-console-wrapper {top: 0;Max-height: 100%重要;}
toJSON方法
如果你想调用JSON。如果在类对象上使用stringify,则需要重写toJSON方法以返回实例数据。
class Cat { constructor(options = {}) { this.name = options.name ?? ''; this.age = options.age ?? 0; } toString() { return `[Cat name="${this.name}", age="${this.age}"]` } toJSON() { return { name: this.name, age: this.age }; } static fromObject(obj) { const { name, age } = obj ?? {}; return new Cat({ name, age }); } } /* * JSON Set adds the missing methods: * - toJSON * - toString */ class JSONSet extends Set { constructor(values) { super(values) } toString() { return super .toString() .replace(']', ` ${[...this].map(v => v.toString()) .join(', ')}]`); } toJSON() { return [...this]; } } const cats = new JSONSet([ Cat.fromObject({ name: 'Furball', age: 2 }), Cat.fromObject({ name: 'Artemis', age: 5 }) ]); console.log(cats.toString()); console.log(JSON.stringify(cats, null, 2)); .as-console-wrapper { top: 0; max-height: 100% !important; }
你不能直接字符串化Map实例,因为它没有任何属性,但你可以将它转换为一个元组数组:
jsonText = JSON.stringify(Array.from(map.entries()));
反之,使用
map = new Map(JSON.parse(jsonText));
只是想分享我的Map和Set JSON版本。stringify。 我正在对它们进行排序,对调试有用……
function replacer(key, value) {
if (value instanceof Map) {
const reducer = (obj, mapKey) => {
obj[mapKey] = value.get(mapKey);
return obj;
};
return [...value.keys()].sort().reduce(reducer, {});
} else if (value instanceof Set) {
return [...value].sort();
}
return value;
}
用法:
const map = new Map();
const numbers= new Set()
numbers.add(3);
numbers.add(2);
numbers.add(3);
numbers.add(1);
const chars= new Set()
chars.add('b')
chars.add('a')
chars.add('a')
map.set("numbers",numbers)
map.set("chars",chars)
console.log(JSON.stringify(map, replacer, 2));
结果:
{
"chars": [
"a",
"b"
],
"numbers": [
1,
2,
3
]
}
我真不知道为什么这里有这么多冗长的笑话。这个简短的版本解决了我的问题:
const data = new Map()
data.set('visible', true)
data.set('child', new Map())
data.get('child').set('visible', false)
const str = JSON.stringify(data, (_, v) => v instanceof Map ? Object.fromEntries(v) : v)
// '{"visible":true,"child":{"visible":false}}'
const recovered = JSON.parse(str, (_, v) => typeof v === 'object' ? new Map(Object.entries(v)) : v)
// Map(2) { 'visible' => true, 'child' => Map(1) { 'visible' => false } }