先记住这个答案
字符串里的反斜杠是转义符,它和后面的字符合起来表示一个特殊字符,比如 \n 是换行,\' 是单引号。反斜杠本身要写成 \\。嵌入 Unicode 字符有两种写法:\u 加正好 4 位十六进制,比如 \u4E2D 是「中」;超出 U+FFFF 的字符(大部分表情符号)用 ES2015 新增的 \u{1F600},花括号里直接写码点。
- 反斜杠本身写
\\,源码两个字符,实际只算一个 \u后必须正好 4 位十六进制- 超出 BMP 的码点可用
\u{...} String.raw可以让反斜杠原样保留
常用转义一次看全
平时最常用的是换行 \n、制表 \t、回车 \r、引号和反斜杠。它们在源码里占两个字符,进到字符串里只算一个。
const a = 'line1\nline2'
console.log(a.length) // \n 只算 1 个字符
console.log('C:\\temp'.length, 'C:\\temp') // 两个反斜杠才是一个
console.log('\u4E2D\u6587') // 4 位十六进制,BMP 内字符
console.log('\u{1F600}'.length) // 码点写法,表情占 2 个码元
console.log('\uD83D\uDE00' === '\u{1F600}') // 代理对写法等价
console.log('\x41', '\'', "\"") // \x 是两位十六进制
console.log(String.raw`C:\new\table`) // raw 不处理转义查看输出与解释
11
7 C:\temp
中文
2
true
A ' "
C:\new\table'C:\\temp' 在源码里有 8 个字符,但实际字符串是 C:\temp,长度 7。如果只写一个反斜杠,'C:\temp' 里的 \t 会被当成制表符,路径就错了。
四位 \u 为什么不够用
JavaScript 字符串内部按 UTF-16 存储,每个存储单元叫一个码元,是 16 位。\u 后面的 4 位十六进制正好对应一个码元,最大 FFFF。常用汉字、拉丁字母都在这个范围里。
表情符号 😀 的码点是 U+1F600,超出了一个码元的容量,要用两个码元组成的「代理对」来存,也就是 \uD83D\uDE00。以前只能这样手算代理对,很不方便。ES2015 加了 \u{...} 写法,花括号里直接写码点,引擎自己拆成代理对。
- 位数写错会直接报错
\u后面不足 4 位,比如'\u4E',在普通字符串里是语法错误,整段脚本都跑不起来。同样,\u{110000}超过了 Unicode 的最大码点,也是语法错误。而'\u4E2D1'不会报错,它是「中」后面跟一个字符 1,因为\u只吃 4 位。
路径和正则里的双重转义
new RegExp('\\d+') 为什么要写两个反斜杠?因为这里经过了两层解析:字符串字面量先把 \\ 变成一个 \,得到 \d+,正则再把 \d 解释成数字。只写 '\d+' 的话,字符串阶段 \d 不是合法转义,反斜杠被丢掉,正则收到的就是 d+。
路径、正则、LaTeX 这类反斜杠很多的内容,可以用 String.raw 标签模板,里面的反斜杠原样保留,不用一个个翻倍。
容易答错的地方
- 以为
\u能写任意长度 \u固定吃后面 4 位,写\u1F600会得到\u1F60对应的字符再跟一个 0,不是笑脸。要写码点必须加花括号。- 以为接口返回的
\n会自动换行 - 转义只在源码解析时生效。如果后端返回的 JSON 字符串被多转义了一层,前端拿到的是反斜杠和字母 n 两个字符,页面不会换行。这时要排查数据是否被重复转义,而不是在前端再套一层
replace。 - 把
\0后面接数字 \0表示空字符,但\01这类后面接数字的是旧的八进制转义,严格模式和模板字符串里都是语法错误。需要空字符后跟数字时写成\x00。
面试官还会怎么问?
模板字符串里的转义规则一样吗?
基本一样,\n、\u{...} 都能用,另外反引号本身要在前面加反斜杠转义,想原样输出 ${ 也要在美元符号前加反斜杠。区别是模板字符串直接写的换行会被保留,不需要 \n。
怎么拿到一个字符的码点,或者用码点生成字符?
用 codePointAt(0) 拿码点,String.fromCodePoint(0x1F600) 生成字符。老的 charCodeAt 和 fromCharCode 只处理单个码元,遇到表情会拿到代理对里的一半。
JSON 里的转义和 JS 字符串一样吗?
JSON 更严格:只能用双引号,只支持 \uXXXX 四位写法,不支持 \u{...}、\x 和单引号转义。JSON.parse 遇到这些会抛 SyntaxError。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。