地图对象的JSON.stringify返回空

GAK*_*GAK 7 javascript json

    var map1= new Map();
    map1.set("one",1);
    var map2 = new Map();
    map2.set("two",2);
   concatMap = {};
   concatMap['one']= map1;
   concatMap['two']= map2;
 JSON.stringify(concatMap);
Run Code Online (Sandbox Code Playgroud)

//输出:“ {”一个“:{},”两个“:{}}”

我也尝试过:

concatMap = {};
concatMap.one= map1;
concatMap.two= map2;
Run Code Online (Sandbox Code Playgroud)

为什么在使用JSON.stringify()时得到空对象而不是地图1和地图2?

Yac*_*ine 12

基本解决方案:

首先如果你有

const map = new Map();
Run Code Online (Sandbox Code Playgroud)

你可以这样设置值:

map.set('key', 'value');
Run Code Online (Sandbox Code Playgroud)

Object.stringify 将发出并清空对象。

你可以这样解决这个问题:

const objFromMap = Object.fromEntries(map);
JSON.stringify(objFromMap);
Run Code Online (Sandbox Code Playgroud)

复杂对象:

如果您有一个对象的映射字段,例如:

class MyClazz {
   field = new Map();
}
const instance = new MyClazz();
instance.field.set('k', 'v');
Run Code Online (Sandbox Code Playgroud)

JSON.stringify 将产生:

{field: {}}
Run Code Online (Sandbox Code Playgroud)

要解决这个问题,请重写 toJSON 方法。你将拥有:

class MyClazz {
   field = new Map();
   toJSON(): this {
      return {
          field: Object.fromEntries(this.field),
      }
   }
}
const instance = new MyClazz();
instance.field.set('k', 'v');
Run Code Online (Sandbox Code Playgroud)

然后,当使用 JSON.stringify(instance); 时 我们会有 :

{field: {k: 'v'}}
Run Code Online (Sandbox Code Playgroud)


Ale*_*ara 5

这是预期的结果。JSON.stringify不能将Map对象识别为与常规对象不同的任何东西,并且JSON规范本身无法正确存储Map。它只是将地图视为常规对象,可能包括在其上设置的任何自己的对象属性。

var m = new Map();

// This is not included:
m.set('test', 123);

// This would be included:
m['other'] = 456;

console.log(JSON.stringify(m));
Run Code Online (Sandbox Code Playgroud)

如果仅使用字符串键,则可以使用常规对象而不是Map。

  • 我不知道我尝试了多少个小时来调试我看似空的地图。事实证明,数据一直都在那里。有什么方法可以记录地图内容而不循环遍历它? (2认同)

Mar*_* CR 5

感谢 Tim Brown 在他关于该主题的博客文章中的贡献- 当 Map 对象的内容可序列化时,您可以执行以下操作:

  1. 将 Map 序列化为 JSON:

    JSON.stringify(Array.from(map.entries()))

  2. 将 JSON 反序列化为 Map:

    new Map(JSON.parse(jsonStr))