JavaScript 常用转义字符一览
字符串里有些字符没法直接写出来。换行会把代码断成两行导致语法错误,引号会提前结束字符串,还有一批控制字符压根没有可见的字形。转义序列就是用来解决这个问题的:以反斜杠 \ 开头,后面跟一个字符或编码,由引擎在解析阶段把它替换成对应的真实字符。
关键要记住转义发生在解析期而不是运行时。'a\nb' 这个字符串在内存里是三个字符——a、换行符、b——长度是 3 而不是 4,反斜杠只存在于我们写的源码里。下面先列常用的一组,再看非特殊字符、反斜杠自身以及 Unicode 编码这几种情况。
常用转义字符
\0 :null(\u0000)
\b :后退键(\u0008)
\f :换页符(\u000C)
\n :换行符(\u000A)
\r :回车键(\u000D)
\t :制表符(\u0009)
\v :垂直制表符(\u000B)
\' :单引号(\u0027)
\" :双引号(\u0022)
\\ :反斜杠(\u005C)
括号里的那串是同一个字符的 Unicode 码点写法,两种形式完全等价,写 \n 和写它对应的码点转义得到的是同一个字符。实际用得最多的是下面这几个:
\n换行,写多行文本、拼接日志时必用。\t制表符,用来对齐控制台输出。\'和\"转义引号,字符串里出现和定界符相同的引号时需要。不过更省事的办法是换定界符,比如内容里有单引号就用双引号包起来,"it's"不需要转义。\\反斜杠自身,写 Windows 路径和正则字面量时躲不开。
\b、\f、\v 这几个来自打字机时代的控制字符现在基本用不到。\b 尤其容易误会:在字符串里它是退格符,而在正则表达式里 \b 表示单词边界,写法一样但语义完全不同,别把两者混起来。
示例
\n 在源码里是两个字符,解析后变成一个换行符,所以下面这一行 console.log 会输出两行:
console.log('1\n2');
// 1
// 2
验证一下长度就能确认它只占一个字符的位置:
'1\n2'.length; // 3,不是 4
'a\tb'.charCodeAt(1); // 9,制表符的码点
如果在非特殊字符前面使用反斜杠,则反斜杠会被省略。
这个特性是个双刃剑:它让笔误不会立刻报错,但也意味着写错的转义会被静默吞掉。比如想输出反斜杠加字母,少写一个反斜杠就什么提示都没有,直接丢了。
'\a';
// "a"
如果字符串的正常内容之中,需要包含反斜杠,则反斜杠前面需要再加一个反斜杠,用来对自身转义。
'Prev \\ Next';
// "Prev \ Next"
写 Windows 路径时这一条会集中爆发,每个分隔符都要写两个反斜杠:
const p = 'C:\\Users\\wfly\\note.txt';
console.log(p); // C:\Users\wfly\note.txt
console.log(p.length); // 22,反斜杠各占一个字符
正则字面量里也是同一个问题的变体。用 new RegExp 时正则要先当字符串解析一遍,所以匹配一个反斜杠需要写四个,用字面量写法则只要两个:
/\\/.test('a\\b'); // true,字面量里写两个
new RegExp('\\\\').test('a\\b'); // true,字符串里得写四个
用 Unicode 转义表示任意字符
除了上面这些固定的转义序列,还有两种按码点写字符的形式:
'\x41'; // "A",\xXX 两位十六进制,只能表示 0-255
'\u4e2d'; // "中",\uXXXX 四位十六进制,表示基本多文种平面内的字符
'\u{1f600}'; // "😀",ES6 新增,花括号里可以写超过四位的码点
前两种是老写法,\uXXXX 只有四位,表示不了码点超过 0xFFFF 的字符(emoji、部分生僻汉字),只能拆成两个代理对写。ES6 的 \u{...} 没有这个限制,需要写这类字符时优先用它。
模板字符串里的差异
模板字符串(反引号包裹)本身支持换行,所以多行文本不再需要 \n,但其他转义序列依然生效,反斜杠和反引号仍需转义:
const s = `第一行
第二行`; // 直接换行,不用 \n
`反引号要转义:\``;
需要拿到未经转义处理的原始文本时,可以用 String.raw。它把转义序列原样保留,写正则和路径时很省心:
String.raw`C:\Users\wfly`; // "C:\Users\wfly",反斜杠不用双写
String.raw`a\nb`; // "a\nb",四个字符,\n 没被转义成换行
一个容易忽略的坑
JSON 有自己的一套转义规则,和 JavaScript 字符串不完全一样。最典型的是 JSON 不支持 \x 和 \',所以 JSON.parse("'\\x41'") 会抛错。手写 JSON 字符串时,转义应该交给 JSON.stringify 处理,它会按 JSON 规范正确编码,不要自己拼:
JSON.stringify('a\nb'); // '"a\\nb"',换行被正确编码
JSON.parse('"a\\nb"'); // "a\nb",解析回真实的换行符

还没有留言,来发表第一条吧~