7.6 JSON 与 Symbol

7.6.1 用 JSON.stringify() 生成 JSON

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 才会有这样的键。

7.6.2 用 JSON.parse() 解析 JSON

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 。

results matching ""

    No results matching ""