我想开始使用ES6地图而不是JS对象,但我被阻止了,因为我不知道如何JSON.stringify()一个地图。我的键保证是字符串,我的值总是会被列出。我真的必须写一个包装器方法来序列化吗?


当前回答

JSON。stringify和JSON。解析支持第二个参数。替换器和恢复器分别。使用下面的replacer和reviver,可以添加对原生Map对象的支持,包括深度嵌套的值

function replacer(key, value) {
  if(value instanceof Map) {
    return {
      dataType: 'Map',
      value: Array.from(value.entries()), // or with spread: value: [...value]
    };
  } else {
    return value;
  }
}
function reviver(key, value) {
  if(typeof value === 'object' && value !== null) {
    if (value.dataType === 'Map') {
      return new Map(value.value);
    }
  }
  return value;
}

用法:

const originalValue = new Map([['a', 1]]);
const str = JSON.stringify(originalValue, replacer);
const newValue = JSON.parse(str, reviver);
console.log(originalValue, newValue);

深度嵌套与数组,对象和映射的组合

const originalValue = [
  new Map([['a', {
    b: {
      c: new Map([['d', 'text']])
    }
  }]])
];
const str = JSON.stringify(originalValue, replacer);
const newValue = JSON.parse(str, reviver);
console.log(originalValue, newValue);

其他回答

Stringify Map实例(对象作为键是可以的):

JSON.stringify([...map])

or

JSON.stringify(Array.from(map))

or

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

输出格式:

// [["key1","value1"],["key2","value2"]]

你不能。

映射的键可以是任何东西,包括对象。但是JSON语法只允许字符串作为键。所以一般情况下是不可能的。

我的键肯定是字符串,我的值总是列表

在这种情况下,您可以使用普通对象。它将有以下优势:

它可以被字符串化为JSON。 它可以在旧的浏览器上运行。 这样可能会更快。

尽管在某些情况下,如果你是地图的创建者,你会在一个单独的“src”文件中编写代码,并将副本保存为.txt文件,如果写得足够简洁,可以很容易地读取、破译并添加到服务器端。

然后,新文件将被保存为.js文件,并从服务器发回对该文件的引用。一旦作为JS读入,该文件将完美地重构自身。美妙之处在于重构时不需要笨拙的迭代或解析。

只是想分享我的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
  ]
}

使用spread sytax Map可以在一行中序列化:

JSON.stringify([...new Map()]);

并反序列化它:

let map = new Map(JSON.parse(map));