为什么 `<newline>` === `\n` 为真,而 `\r\n` === `\n` 为假?

Why is `<newline>` === `\n` true but `\r\n` === `\n` is false?

其中有不同的控件character/sequence,代表不同平台的新行。根据模板文字解释的规则,在任何平台JavaScript 代码是运行 下,文字中的新行必须规范化为换行(\n)。在spec<CR><LF> and <CR> LineTerminatorSequences are normalized to <LF> for both TV and TRV.

方面

所以它 returns 正确:

`foo
boo` === `foo\nboo`

但是,当我们显式放置换行的不同表示时,此逻辑不适用:

`foo\nboo` === `foo\r\nboo` // false
`foo\nboo` === `foo\rboo` // false

为什么JavaScript区分这两种情况?它们有什么区别?

the ECMAScript specification中的注释全文如下:

TV excludes the code units of LineContinuation while TRV includes them. <CR><LF> and <CR> LineTerminatorSequences are normalized to <LF> for both TV and TRV. An explicit EscapeSequence is needed to include a <CR> or <CR><LF> sequence.

添加了重点。

这意味着 `\r\n``\r` 被保留。因此,代码按预期工作:

console.log([...`\r\n`]);
console.log([...`\r`]);
console.log([...`
`]);
.as-console-wrapper { max-height: 100% !important; }

注意

'\u000A\u000D' === '\n\r'`

因为 \n\r 只是给定控制字符的别名。

您还可以在

中看到对 LF 的标准化
eval("`\n\r`") === "\n\n"

每个字符变为 LF,并且

eval("`\r\n`") === "\n"

CR+LF 变成 LF。 但同样,这仅适用于源 parsing 阶段(因此 eval),在文字中显式使用它或从外部资源读取字符串时无需“隐藏”规范化,所以比较将按预期进行。