我想开始使用ES6地图而不是JS对象,但我被阻止了,因为我不知道如何JSON.stringify()一个地图。我的键保证是字符串,我的值总是会被列出。我真的必须写一个包装器方法来序列化吗?
当前回答
更好的解决方案
// somewhere...
class Klass extends Map {
toJSON() {
var object = { };
for (let [key, value] of this) object[key] = value;
return object;
}
}
// somewhere else...
import { Klass as Map } from '@core/utilities/ds/map'; // <--wherever "somewhere" is
var map = new Map();
map.set('a', 1);
map.set('b', { datum: true });
map.set('c', [ 1,2,3 ]);
map.set( 'd', new Map([ ['e', true] ]) );
var json = JSON.stringify(map, null, '\t');
console.log('>', json);
输出
> {
"a": 1,
"b": {
"datum": true
},
"c": [
1,
2,
3
],
"d": {
"e": true
}
}
希望这比上面的答案不那么尴尬。
其他回答
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);
下面的方法将Map转换为JSON字符串:
public static getJSONObj(): string {
return JSON.stringify(Object.fromEntries(map));
}
例子:
const x = new Map();
x.set("SomeBool", true);
x.set("number1", 1);
x.set("anObj", { name: "joe", age: 22, isAlive: true });
const json = getJSONObj(x);
// Output:
// '{"SomeBool":true,"number1":1,"anObj":{"name":"joe","age":222,"isAlive":true}}'
虽然ecmascript还没有提供方法,但这仍然可以使用JSON来完成。如果将map映射到JavaScript原语,则使用stingify。下面是我们将使用的Map示例。
const map = new Map();
map.set('foo', 'bar');
map.set('baz', 'quz');
转到JavaScript对象
你可以用下面的辅助函数转换成JavaScript对象文字。
const mapToObj = m => {
return Array.from(m).reduce((obj, [key, value]) => {
obj[key] = value;
return obj;
}, {});
};
JSON.stringify(mapToObj(map)); // '{"foo":"bar","baz":"quz"}'
转到JavaScript对象数组
这个函数的辅助函数将更加紧凑
const mapToAoO = m => {
return Array.from(m).map( ([k,v]) => {return {[k]:v}} );
};
JSON.stringify(mapToAoO(map)); // '[{"foo":"bar"},{"baz":"quz"}]'
进入数组的数组
这个更简单,你可以用
JSON.stringify( Array.from(map) ); // '[["foo","bar"],["baz","quz"]]'
更好的解决方案
// somewhere...
class Klass extends Map {
toJSON() {
var object = { };
for (let [key, value] of this) object[key] = value;
return object;
}
}
// somewhere else...
import { Klass as Map } from '@core/utilities/ds/map'; // <--wherever "somewhere" is
var map = new Map();
map.set('a', 1);
map.set('b', { datum: true });
map.set('c', [ 1,2,3 ]);
map.set( 'd', new Map([ ['e', true] ]) );
var json = JSON.stringify(map, null, '\t');
console.log('>', json);
输出
> {
"a": 1,
"b": {
"datum": true
},
"c": [
1,
2,
3
],
"d": {
"e": true
}
}
希望这比上面的答案不那么尴尬。
你不能直接字符串化Map实例,因为它没有任何属性,但你可以将它转换为一个元组数组:
jsonText = JSON.stringify(Array.from(map.entries()));
反之,使用
map = new Map(JSON.parse(jsonText));
推荐文章
- 使嵌套JavaScript对象平放/不平放的最快方法
- 如何以及为什么'a'['toUpperCase']()在JavaScript工作?
- 有Grunt生成index.html不同的设置
- 文档之间的区别。addEventListener和window。addEventListener?
- 如何检查动态附加的事件监听器是否存在?
- 如何写setTimeout与参数Coffeescript
- 将JavaScript字符串中的多个空格替换为单个空格
- JavaScript: override alert()
- 重置setTimeout
- 如何确保<select>表单字段被禁用时提交?
- jQuery有不聚焦的方法吗?
- 在STL地图中,使用map::insert比[]更好吗?
- 反应钩子-正确的方式清除超时和间隔
- 在VS Code中禁用“Comments are not allowed In JSON”错误
- TypeScript枚举对象数组