diff --git a/docs/proposals.md b/docs/proposals.md index bc68caa..929adbb 100644 --- a/docs/proposals.md +++ b/docs/proposals.md @@ -160,3 +160,33 @@ a?.b = 42 // 如果 a 是 null 或 undefined,下面的语句不产生任何效果 delete a?.b ``` + +## 直接输入 U+2028 和 U+2029 + +JavaScript 字符串允许直接输入字符,以及输入字符的转义形式。举例来说,“中”的 Unicode 码点是 U+4e2d,你可以直接在字符串里面输入这个汉字,也可以输入它的转义形式`\u4e2d`,两者是等价的。 + +```javascript +'中' === '\u4e2d' // true +``` + +但是,JavaScript 规定有5个字符,不能在字符串里面直接使用,只能使用转义形式。 + +- U+005C:反斜杠(reverse solidus) +- U+000D:回车(carriage return) +- U+2028:行分隔符(line separator) +- U+2029:段分隔符(paragraph separator) +- U+000A:换行符(line feed) + +举例来说,字符串里面不能直接包含反斜杠,一定要转义写成`\\`或者`\u005c`。 + +这个规定本身没有问题,麻烦在于 JSON 格式允许字符串里面直接使用 U+2028(行分隔符)和 U+2029(段分隔符)。这样一来,服务器输出的 JSON 被`JSON.parse`解析,就有可能直接报错。 + +JSON 格式已经冻结(RFC 7159),没法修改了。为了消除这个报错,现在有一个[提案](https://github.com/tc39/proposal-json-superset),允许 JavaScript 字符串直接输入 U+2028(行分隔符)和 U+2029(段分隔符)。 + +```javascript +const PS = eval("'\u2029'"); +``` + +根据这个提案,上面的代码不会报错。 + +注意,模板字符串现在就允许直接输入这两个字符。另外,正则表达式依然不允许直接输入这两个字符,这是没有问题的,因为 JSON 本来就不允许直接包含正则表达式。