Search code examples
javascripttemplate-literals

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


There are different control character/sequence of them which represent(s) a new line with regard to different platforms. In accordance with the rules of template literals interpretation, under whatever platform JavaScript code is running, a new line within the literal must be normalized to line feed (\n). In terms of the spec, <CR><LF> and <CR> LineTerminatorSequences are normalized to <LF> for both TV and TRV.

So it returns true:

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

However, this logic is not applicable when we explicitly put the different representations of new line:

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

Why does JavaScript distinguish these two cases? What is the difference between them?


Solution

  • The full text of the note in the ECMAScript specification is as follows:

    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.

    Emphasis added.

    This means that `\r\n` and `\r` are preserved. Therefore, the code works as expected:

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