词法与基本语法
本篇内容:词法(Unicode、转义序列、注释、字面量、标识符、关键字与保留字)、语句与声明、ASI、变量声明的语法形式、严格模式。属ECMA-262 语言层(§11 词法、§12 语句、§9 执行上下文、§16 脚本与模块的语义)。
白话导读:本文讲 JavaScript 代码最底层的写法规则——怎么写字面量、怎么命名、注释怎么写、分号能不能省、严格模式到底管什么。这些是读任何 JS 代码都会碰到的基础。
一、Unicode 字符集
JavaScript 源码以Unicode字符集编码。标识符与字符串字面量都可以直接使用非 ASCII 字符。
// 变量名可以使用 Unicode 字符const姓名="张三";constπ=3.14159;constcafé="咖啡";// 字符串中可以包含任意 Unicode 字符constgreeting="你好,世界!";constemoji="😀";constmath="∑∫∂";团队协作中通常仍使用英文标识符以保持可读性与一致性——这是风格约定,不是语言要求。
1.1 引擎支持的 Unicode 版本
| 引擎 | Unicode 数据来源 |
|---|---|
| V8(Chrome / Node / Edge) | 跟随 ICU 更新 |
| SpiderMonkey(Firefox) | 跟随 ICU 更新 |
| JavaScriptCore(Safari) | 跟随 ICU 更新 |
规范不规定引擎必须支持哪一个 Unicode 版本。各引擎的实现细节随版本演进,因此不要把某个 Unicode 版本的属性支持(如较新的
\p{...}脚本名、Emoji 序列)当成可移植保证——需要时用特性检测。
1.2 Unicode 相关 API
// 码点"中".codePointAt(0);// 20013String.fromCodePoint(20013);// "中"(ES2015)// 码元(UTF-16 编码单元)"中".charCodeAt(0);// 20013String.fromCharCode(20013);// "中"// 规范化"café".normalize("NFC");// 规范化形式(ES2015)// 大小写"Hello".toUpperCase();// "HELLO""Hello".toLowerCase();// "hello"这些方法属于
String,成员级语义见《2-标准库/03-String与RegExp》。本章只关心它们在词法层的用途:源码字符、字面量内容与标识符合法性。
二、转义序列
转义序列用于表示无法直接在源代码中输入的字符。能出现在正则、字符串与模板中的转义序列集合并不相同——见《2-标准库/03-String与RegExp》。
2.1 字符转义(Unicode)
| 转义序列 | 格式 | 示例 | 说明 |
|---|---|---|---|
| Unicode 转义(4 位十六进制) | \uXXXX | "\u4E2D"→"中" | BMP 内字符,范围\u0000~\uFFFF |
| Unicode 码点转义(大括号) | \u{XXXXXX} | "\u{1F600}"→"😀" | 任意 Unicode 码点,ES2015引入 |
| 十六进制转义(Latin-1) | \xXX | "\x48"→"H" | 仅限0x00~0xFF(编码单元值,不是字节) |
// 表示同一个字符"中"的两种方式"中";// 直接输入"\u4E2D";// Unicode 转义"\u{4E2D}";// Unicode 码点转义// \x 是"编码单元值",不是 UTF-8 字节序列"\x48";// "H"(U+0048)"\xE4";// "ä"(U+00E4)—— 不是 UTF-8 首字节// "\xE4\xB8\xAD" 是三个 Latin-1 字符 "ä¸",不等于 "中"⚠️
\xXX是编码单元值,不是字节转义:它表示一个 UTF-16 编码单元的值,不接受字节序列;"\xE4\xB8\xAD"是"ä¸",不等于"中"。要写"中"用"\u4E2D"或"\u{4E2D}"。
2.2 字符串中的转义字符
| 转义字符 | 说明 | 转义字符 | 说明 |
|---|---|---|---|
\n | 换行(LF) | \\ | 反斜杠 |
\r | 回车(CR) | \' | 单引号 |
\t | 制表符 | \" | 双引号 |
\b | 退格 | 反引号转义 | 反引号(模板字面量中) |
\f | 换页 | \0 | NUL(后面不能紧跟十进制数字) |
\v | 垂直制表 |
constnewline="第一行\n第二行";consttab="列1\t列2";constbackslash="路径:C:\\Users\\John";// 每个反斜杠都要写两次constquote="他说:\"你好\"";2.3 无效与边界情形
// "\u{110000}"; // SyntaxError:超出 Unicode 最大码点"\u{10FFFF}";// 最大码点(合法)// 代理对与码点转义等价"\uD83D\uDE00";// "😀""\u{1F600}";// "😀"(等价)// 非转义字符(NonEscapeCharacter):\ 后跟普通字符时,反斜杠被丢弃"\U";// "U"(反斜杠被丢弃,不是保留字面反斜杠)`C:\Users\John`;// "C:UsersJohn" ← 模板字面量同规则;要保留反斜杠用 String.raw 或 \\String.raw`C:\Users\John`;// "C:\Users\John"(标签模板保留原始文本)2.4 转义序列使用场景
| 场景 | 说明 |
|---|---|
| 嵌入特殊字符 | 换行、制表符等 |
| 编码非 ASCII 字符 | 在纯 ASCII 环境中 |
| 避免引号冲突 | 字符串中包含引号 |
| 表示不可见字符 | 控制字符 |
三、注释
3.1 单行注释与多行注释
// 这是一个单行注释letx=10;// 行尾注释/* * 这是一个多行注释 * 通常用于文件头说明、函数文档等 */functionadd(a,b){returna+b;}/* 多行注释也可以写成单行块的形式 */3.2 注释不能嵌套
// 错误:多行注释不能嵌套/* 外层注释 /* 内层注释 */外层继续*/// 第一个 */ 就提前终止了注释,剩余部分成为代码 → SyntaxError3.3 JSDoc 文档注释
/** * 计算两个数的和 * @param {number} a - 第一个数 * @param {number} b - 第二个数 * @returns {number} 两数之和 */functionadd(a,b){returna+b;}/** * 用户信息 * @typedef {Object} User * @property {number} id - 用户 ID * @property {string} name - 用户名 * @property {string} [email] - 邮箱(可选) *//** * 获取用户 * @param {number} id - 用户 ID * @returns {Promise<User>} 用户信息 * @throws {NotFoundError} 用户不存在时抛出 */asyncfunctiongetUser(id){// ...}| 标签 | 说明 | 标签 | 说明 |
|---|---|---|---|
@param | 参数说明 | @example | 使用示例 |
@returns | 返回值说明 | @deprecated | 标记已废弃 |
@throws | 可能抛出的错误 | @see | 参考链接 |
@typedef | 定义类型 | @since | 引入版本 |
@property | 属性说明 | @author | 作者 |
JSDoc不是ECMA-262 的一部分,它是注释的书写约定,由 TypeScript / IDE / 文档工具解析。语法上它只是普通的多行注释。
3.4 注释规范
| 规范 | 说明 |
|---|---|
| 解释为什么,而非做什么 | 代码说明"做什么",注释说明"为什么" |
| 避免冗余注释 | 不要注释显而易见的内容 |
| 及时更新 | 代码修改时同步更新注释 |
| 避免注释掉的代码 | 用版本控制管理历史 |
| 使用 JSDoc | 为公共 API 添加文档注释 |
letx=10;// ❌ 冗余:"将 x 设为 10"lettimeout=5000;// ✅ 解释原因:"5 秒超时,根据 API 文档要求"四、字面量
字面量是在代码中直接表示值的语法结构。
4.1 字面量类型一览
| 字面量类型 | 示例 | 说明 |
|---|---|---|
| 数字字面量 | 42、3.14、0xFF、1e3、0b1010、1_000 | 整数、浮点、十六进制、科学计数法、二进制、数值分隔符 |
| BigInt 字面量 | 42n、0xFFn | ES2020 |
| 字符串字面量 | "Hello"、'World' | 单引号/双引号 |
| 模板字面量 | `Hello ${name}` | ES2015 |
| 布尔字面量 | true、false | 布尔值 |
null字面量 | null | 表示空值 |
| 对象字面量 | { name: "John" } | 键值对集合 |
| 数组字面量 | [1, 2, 3] | 有序元素列表 |
| 正则表达式字面量 | /abc/g | 正则模式 |
⚠️
undefined不是字面量。它是全局对象上不可写、不可配置的数据属性。见《01-类型系统》第三节。
4.2 数字字面量
// 整数与浮点42;-42;3.14;.5;// 0.55.;// 5.0// 科学计数法1e3;// 1000