ron*_*ler 2 javascript html5 json
我正在开发一个Angular应用程序.我使用Typescript并拥有一个包含内置Set和Map类型的类.我的问题是我想将我的类的实例作为JSON存储在浏览器的localStorage中,但是当我尝试对它们进行字符串化时,我会得到这些类型的空字符串.
chrom的控制台示例:
> inst = new Object({
'elem': new Set(),
'str': 'somestring'
})
: Object {elem: Set(0), str: "somestring"}elem: Set(0)str: "somestring"}
> inst.elem.add('123');
: Set(1) {"123"}
> inst.elem.add('123');
: Set(1) {"123"}size: (...)__proto__: Set[[Entries]]: Array(1)0: "123"length: 1
> JSON.stringify(inst)
: "{"elem":{},"str":"somestring"}"
Run Code Online (Sandbox Code Playgroud)
我唯一能想到的是在字符串化之前将Sets和Maps分别递归转换为Arrays和Objects.但这听起来很费劲.
有没有更好的办法?谢谢.
将Map转换为简单对象将不起作用,除非键恰好是所有字符串.请记住,地图可以包含任何键作为键,包括通过引用不相同但在强制时将导致相同字符串的内容.
实际上,序列化地图和集合的明显方法是将它们转换为数组,然后将其序列化.幸运的是,您不必自己编写很多代码,只需使用内置迭代器:
const map = new Map([['a', 1], ['b', 2]])
const set = new Set([2,3,5,7,11])
serializedMap = JSON.stringify([...map]) // => [["a", 1], ["b", 2]]
serializedSet = JSON.stringify([...set]) // => [2,3,5,7,11]
Run Code Online (Sandbox Code Playgroud)
现在,正如您所注意到的,嵌套地图和集合会遇到一些问题.为避免编写特定代码以深入到对象中并将其深层嵌套的Map和Set值转换为数组,您可以toJSON在Map和Set prototypes上定义方法.该方法由JSON.stringify隐式调用:
Map.prototype.toJSON = function () {
return [...this]
}
// or, if you really want to use objects:
Map.prototype.toJSON = function () {
var obj = {}
for(let [key, value] of this)
obj[key] = value
return obj
}
// and for Sets:
Set.prototype.toJSON = function () {
return [...this]
}
Run Code Online (Sandbox Code Playgroud)
请注意,toJSON可能会在将来某个时间为"集合"和"地图"定义,但行为与此不同.虽然看起来不太可能.
现在,无论何时调用JSON.stringify并看到Map或Set,它都会注意到该toJSON方法并使用它而不是仅仅复制对象的属性.
另一个类似的ECMA批准的解决方案是使用JSON.stringify第二个参数.定义一个辅助函数,它将预处理值,用适当的数组或对象替换Maps和Sets:
function mapReplacer(key, value) {
if(value instanceof Map || value instanceof Set) {
return [...value]
// of course you can separate cases to turn Maps into objects
}
return value
}
Run Code Online (Sandbox Code Playgroud)
现在只需传递mapReplacer给JSON.stringify:
JSON.stringify(map, mapReplacer)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1534 次 |
| 最近记录: |