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


当前回答

你不能。

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

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

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

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

其他回答

鉴于您的示例是一个简单的用例,其中键将是简单类型,我认为这是JSON stringify Map的最简单方法。

JSON.stringify(Object.fromEntries(map));

我认为Map的底层数据结构是键值对数组(数组本身)。就像这样:

const myMap = new Map([
     ["key1", "value1"],
     ["key2", "value2"],
     ["key3", "value3"]
]);

因为底层的数据结构就是我们在Object中找到的。条目,我们可以在Map上使用Object.fromEntries()的原生JavaScript方法,就像在数组上一样:

Object.fromEntries(myMap);

/*
{
     key1: "value1",
     key2: "value2",
     key3: "value3"
}
*/

然后剩下的就是对结果使用JSON.stringify()。

尽管在某些情况下,如果你是地图的创建者,你会在一个单独的“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));

不能调用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; }