JSON.stringify()
将 JavaScript 数据转换成 JSON 字符串。有一个预处理的步骤可以自定义转换:传入一个转换函数,可以将 JavaScript 数据中的任何数据转换成另一种数据。这意味者可以将不兼容 JSON 的值(比如 Symbol 和日期)转换为 JSON 兼容的值(比如字符串)。 JSON.parse()
使用类似的过程解析 JSON 字符串。
但是,stringify
会忽略掉非字符串类型的属性键,所以该方法仅对作为属性值的 Symbol 有效。例如,像这样:
function symbolReplacer(key, value) {
if (typeof value === 'symbol') {
return '@@' + Symbol.keyFor(value) + '@@';
}
return value;
}
const MY_SYMBOL = Symbol.for('http://example.com/my_symbol');
const obj = { myKey: MY_SYMBOL };
const str = JSON.stringify(obj, symbolReplacer);
console.log(str);
// {"myKey":"@@http://example.com/my_symbol@@"}
Symbol 被编码成以'@@'为前缀和后缀的字符串。注意,只有通过 Symbol.for()
创建的 Symbol 才会有这样的键。
JSON.parse()
将 JSON 字符串转换成 JavaScript 数据。有一个后处理步骤可以自定义转换:传入一个转换函数,所谓的_复活器(reviver)_ ,可以将 JSON 字符串中的任何原始串成其它的数据。这样就可以将指定格式的 JSON 数据转换成非 JSON 规范支持的数据了。如下所示:
const REGEX_SYMBOL_STRING = /^@@(.*)@@$/;
function symbolReviver(key, value) {
if (typeof value === 'string') {
const match = REGEX_SYMBOL_STRING.exec(value);
if (match) {
const symbolKey = match[1];
return Symbol.for(symbolKey);
}
}
return value;
}
const parsed = JSON.parse(str, symbolReviver);
console.log(parse);
以‘@@’为前缀和后缀的字符串通过解析中间的 Symbol 键被转换成 Symbol 。