For AI agents: the complete documentation index is available at /tc39-atlas/llms.txt, the full documentation bundle is available at /tc39-atlas/llms-full.txt, and this page is available as Markdown at /tc39-atlas/proposals/stage/4/proposal-json-superset.md.
  • 简体中文
  • JSON superset S4

    中文标题:JSON 超集

    提案概览
    提案速览

    该提案通过允许字符串字面量中未转义的 U+2028 和 U+2029,将 ECMAScript 语法扩展为 JSON 的完整超集,解决了与 JSON.parse 的不一致。该变更向后兼容,并消除了这些罕见字符的 SyntaxError。

    Note

    以下 README 来自上游仓库,其中的阶段或状态标注可能滞后;当前信息以提案概览为准。

    吸收 JSON(又称 JSON ⊂ ECMAScript)

    一个将 ECMA-262 语法扩展为 JSON 超集的提案。

    状态

    该提案处于 TC39 流程 的第 4 阶段,并计划包含在 ES2019 中。

    支持者

    • Mark Miller
    • Mathias Bynens

    动机

    ECMAScript 在 JSON.parse 中声称 JSON 是其子集,但(正如已被充分记录的那样)这并不正确,因为 JSON 字符串可以包含未转义的 U+2028 行分隔符和 U+2029 段落分隔符字符,而 ECMAScript 字符串则不能。

    这些例外给规范增加了不必要的复杂性,并增加了实现者和用户双方的认知负担,可能导致细微的错误引入。 另外,作为一个较小但具体的推论问题,某些源码拼接和构造任务目前需要额外的步骤,才能将有效的 JSON 处理为有效的 ECMAScript 后再嵌入。

    提议的解决方案

    JSON 语法由 ECMA-404 定义,并由 RFC 7159 永久固定,但 ECMA-262 的 DoubleStringCharacterSingleStringCharacter 产生式可以扩展为允许未转义的 U+2028 行分隔符和 U+2029 段落分隔符字符。

    示例

    const LS = "";
    const PS = eval("'\u2029'");

    讨论

    向后兼容性

    此更改是向后兼容的。 对用户可见的影响将仅限于在解析包含未转义的行分隔符或段落分隔符字符的字符串时消除 SyntaxError 完成,这些字符在实践中极不常见(我们还希望收集数据来了解在字符串_外部_将这些字符用作行终止符的频率)。

    正则表达式字面量

    未转义的行分隔符和段落分隔符字符目前在正则表达式字面量中也不允许,但该限制被保留,因为正则表达式字面量不属于 JSON 的一部分。

    模板字面量

    未转义的行分隔符和段落分隔符字符在模板字面量中已经允许。

    有效性

    涵盖 JSON 语法并不意味着所有 JSON 文本的_语义_有效性。 例如,({ "__proto__": 1, "__proto__": 2 }) 在附录 B 下会触发早期 SyntaxError,并且将继续如此。 然而,从 ({ "LineTerminators": "\n\r" }) 生成解析树将成为可能。

    反对意见

    Allen Wirfs-Brock 认为 ECMAScript 和 JSON 是不同的,不需要一个容易描述的关系,并且担心接受此提案会被他人用作试图“修复 JSON”的杠杆。

    后者通过此提案明确承认 JSON 语法是一个固定点来解决。 至于前者,从 JSON.parse 的定义中可以清楚看出 ECMAScript 受益于这种相似性(例如,步骤 4 包括“解析和评估 scriptText,就好像它是 ECMAScript Script 的源文本一样”)。 本提案认为,消除对替代的 DoubleStringCharacter 产生式的需求以及推理两种语言时所关联的认知负担,足以证明这样的变更是有益的。

    符合性测试

    Test262 测试位于:https://github.com/tc39/test262/pull/1544

    TC39 会议记录

    实现

    规范

    规范可在 ecmarkup渲染的 HTML 中获取。