【问题标题】:Serialize Map object with jQuery/JS使用 jQuery/JS 序列化 Map 对象
【发布时间】:2018-03-26 06:06:05
【问题描述】:

[这是关于 SO 的第一个问题,如有错误请见谅]

我正在尝试将如下图所示的地图保存在 cookie 中。

var myMap = new Map();
myMap.set("k1", {
    a1: "...",
    a2: "...",
    a3: "..."
});

为此,我必须格式化为 JSON。我尝试了很多方法,例如:

$.toJSON(myMap)
$.param(myMap)
JSON.stringify(myMap)

但它们似乎都不起作用......

所以,我这样做了:

var serial = [];
myMap.forEach(function(value){
    serial.push(value);
});
var result = $.toJSON(serial)

(必须重构解码 JSON 的密钥...)

有更好的方法来序列化 Map 对象吗?

【问题讨论】:

    标签: javascript jquery json dictionary serialization


    【解决方案1】:

    不完全是典型的“字符串化”,但您可以使用扩展运算符结合JSON.stringify(),这将为您提供一个数组...

    var myMap = new Map();
    myMap.set("k1", { a1: "...", a2: "...", a3: "..." });
    myMap.set("k2", { b1: "...", b2: "...", b3: "..." });
    
    var myJSON = JSON.stringify([...myMap]);
    alert(myJSON);
    

    这会给你...

    [["k1",{"a1":"...","a2":"...","a3":"..."}],["k2",{"b1":"...","b2":"...","b3":"..."}]]
    

    并再次将其转换为地图...

    var recoveredMap = new Map(JSON.parse(myJSON));
    

    【讨论】:

    • 这很好用,但旧版浏览器不支持。检查here 的兼容性。
    【解决方案2】:

    虽然如果您想对直接映射进行字符串化,展开运算符很好,但如果它们嵌套在任何数据结构中,您将面临问题。

    JSON.stringify 和 JSON.parse 都支持回调函数:

    JSON.stringify(value[, replacer[, space]])
    JSON.parse(text[, reviver])
    

    所以你可以编写如下函数:

    function replacer (key, value){
        if (value.__proto__ == Map.prototype) {
            return {
                _type: "map",
                map: [...value],
            }
        } else return value;
    }
    
    function reviver (key, value){
        if (value._type == "map") return new Map(value.map);
        else return value;
    }
    

    现在无论嵌套多深,您都可以轻松地对地图进行字符串化/解析:

    let obj = {
        map: new Map([
            [1, new Map([
                [1,2],
                [3,4],
            ])],
            [2,3],
        ]),
    };
    console.log(obj);
    let str = JSON.stringify(obj, replacer);
    console.log(str);
    console.log(JSON.parse(str));
    console.log(JSON.parse(str, reviver));
    

    【讨论】:

      【解决方案3】:

      如何使用Array.from 将您的Map 转换为数组

      // initialize the map
      var myMap = new Map();
      myMap.set("k1", {
        a1: "...",
        a2: "...",
        a3: "..."
      });
      myMap.set("k2", {
        a1: "...",
        a2: "...",
        a3: "..."
      });
      
      
      // serialize the map by converting it to an array
      var mapAsArray = Array.from(myMap);
      console.log('Map as array ',mapAsArray);
      
      var serializedMap = JSON.stringify(mapAsArray);
      console.log(serializedMap)
      
      // deserialize into a new map
      var map = new Map(JSON.parse(serializedMap))
      console.log(map.size)

      【讨论】:

        【解决方案4】:

        有一个新的 JS 功能 - Object.fromEntries。它可以将地图解析为对象

        const obj = {a: 1, b: 2}
        const map = new Map(Object.entries(obj))
        const objectCopy = Object.fromEntries(map)
        
        

        兼容性没问题(Chrome、FF、Safari)并且存在 polyfill。我们还可以期待兼容性扩展到所有浏览器,因为 fromEntries 是“第 4 阶段”提案(已批准)。
        查看兼容性here

        【讨论】:

          猜你喜欢
          • 2015-03-26
          • 1970-01-01
          • 2013-10-06
          • 2014-10-12
          • 1970-01-01
          • 2017-04-06
          • 2012-04-16
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多