ECMAScript 2017:为何EscapeSequence包含NonEscapeCharacter?
Great question! Let's unpack this using the ECMAScript 2017 spec snippets you provided.
First, let's recap the relevant spec bits for clarity:
11.8.4 字符串字面量,注1 字符串字面量是由单引号或双引号包裹的零个或多个Unicode代码点。Unicode代码点也可通过转义序列表示。……任意代码点均可以转义序列的形式出现。
11.8.4 字符串字面量,语法 非终结符EscapeSequence的词法文法产生式如下:EscapeSequence :: CharacterEscapeSequence 0 [lookahead ∉ DecimalDigit] HexEscapeSequence…
While the spec snippet you shared doesn't explicitly list NonEscapeCharacter as a production rule for EscapeSequence, it's part of the full ES2017 grammar (an oversight in the snippet you provided). So why does this rule exist? Here are the key reasons:
Backward Compatibility
Early versions of JavaScript (like ES3) allowed escaping any character, even those that didn't require escaping (e.g.,\q,\xwherexisn't part of a hex escape). To avoid breaking existing code that relied on this behavior, subsequent specs (including ES2017) retained this rule. It's a classic case of preserving legacy support while evolving the language.Grammar Robustness & Error Tolerance
By allowing\followed by any non-escape character, the spec makes the string literal syntax more forgiving. If a developer accidentally adds a backslash before a regular character (say, typing\zinstead of justz), the code won't throw a syntax error. Instead, the escape sequence is treated as the literal character itself (so\zevaluates toz). This reduces accidental bugs in hand-written or dynamically generated code.Consistency in Code Generation
When generating string literals programmatically (e.g., from templates, code generators, or transpilers), it's often easier to unconditionally escape certain characters (or even all characters) rather than checking which ones actually need escaping. TheNonEscapeCharacterrule lets this approach work without invalidating the generated code. For example, a generator might escape every character in a string, and the result will still be valid JS.
In short, this rule exists to balance language evolution with practicality—keeping old code working, making the syntax more forgiving, and simplifying code generation workflows.
内容的提问来源于stack exchange,提问作者Magnus

