JavaScript 语法速查表 - JavaScript 常用方法与技巧大全
这套速查给写 React/Vue、Node 脚本或任何前端项目的开发者,聚焦每天都要用的 ES6+ 语法:变量与函数、解构、模板字符串、数组高阶方法、异步与模块。与把 API 照名罗列的文档不同,这里按"这句代码解决什么问题"组织,可边看边抄。读完你应能写出不靠 var 的块级变量、用解构抽取值、用 map/filter 取代手写 for,并用 async/await 把回调整理清楚。
典型使用场景
面向写浏览器与 Node.js 代码的 JavaScript 开发者。本表把语言核心按「变量与函数 → 解构 → 字符串 → 数组方法 → 异步 → 模块 → 对象与类」组织,每个分组都是实际写业务代码时用得最多的部分。三处最值得注意:解构在函数参数位置可直接展开对象并带默认值;数组方法 map/filter/reduce 覆盖了绝大多数数据处理;Promise 的 all/race/allSettled 三者语义不同,选错会直接改变行为。
变量与函数 Variables & Functions 6
const name = "value"let count = 0const fn = (x) => x * 2const fn = (x, y = 1) => {}const fn = (...args) => {}function* generator() { yield 1; }解构赋值 Destructuring 5
const [a, b] = [1, 2]const { name, age } = personconst { name: userName } = personconst [first, ...rest] = arrfunction fn({ name, age = 18 }) {}字符串与模板 String & Template 6
`Hello ${name}`str.includes("text")str.startsWith("prefix")str.endsWith("suffix")str.padStart(10, "0")str.trim() / trimStart() / trimEnd()数组方法 Array Methods 8
arr.map(x => x * 2)arr.filter(x => x > 0)arr.reduce((acc, x) => acc + x, 0)arr.find(x => x.id === 1)arr.findIndex(x => x > 0)arr.some(x => x > 0) / every(x => x > 0)arr.flat() / flatMap()Array.from(iterable) / Array.of(1,2,3)异步编程 Async/Await 6
const p = new Promise((resolve, reject) => {})p.then(res => {}).catch(err => {})async function fn() { await p; }Promise.all([p1, p2])Promise.race([p1, p2])Promise.allSettled([p1, p2])模块 Modules 6
import { name } from "./module.js"import * as utils from "./utils.js"import defaultExport from "./module.js"export const name = "value"export default function() {}export { name, age }对象与类 Object & Class 6
const obj = { name, age }const obj = { fn() {} }const obj = { [`key${i}`]: value }Object.keys(obj) / values(obj) / entries(obj)class MyClass { constructor() {} }class Child extends Parent {}参数矩阵
| 参数 | 作用 | 示例 |
|---|---|---|
const vs let | 不可重新赋值 / 可重新赋值,均为块级作用域 | const name = "value" |
箭头函数 | 省略 return,不绑定自己的 this | const fn = (x) => x * 2 |
默认参数 | 仅未传或显式传 undefined 时生效 | const fn = (x, y = 1) => {} |
剩余参数 ...rest | 收集多余实参为真数组 | const fn = (...args) => {} |
function* / yield | 生成器,惰性按需产出 | function* generator() { yield 1; } |
数组解构 + 剩余 | 取首项与剩余项 | const [first, ...rest] = arr |
对象解构重命名 | 属性名与变量名不一致时 | const { name: userName } = person |
函数参数解构 | 形参直接展开并可带默认值 | function fn({ name, age = 18 }) {} |
模板字符串 | 插值与多行 | `Hello ${name}` |
map / filter / reduce | 映射 / 过滤 / 归约(均返回新值) | arr.reduce((acc, x) => acc + x, 0) |
find / findIndex | 找第一个元素 / 索引 | arr.find(x => x.id === 1) |
some / every | 任一满足 / 全部满足(短路) | arr.every(x => x > 0) |
flat / flatMap | 扁平化数组 | arr.flat() |
Promise.all / race / allSettled | 全成功 / 最先完成 / 等全部不论成败 | Promise.allSettled([p1, p2]) |
import / export | ESM 具名与默认导出 | export const name = "value" |
易错点与避坑指南
现象循环里用 var 定义变量,结果所有项都指向最后一个值。
原因var 是函数作用域而非块级作用域,循环结束后仍共享同一个绑定。
处置改用 let 或 const 获得块级作用域。
现象把箭头函数当对象方法,this 指向了外层而非对象。
原因箭头函数没有自己的 this,会捕获定义时的 this。
处置对象方法用 function 简写形式,需要调用对象自身时保留 this。
现象forEach 里用 async 函数,循环却没等异步完成。
原因forEach 不等待回调返回的 Promise。
处置改用 for...of 配合 await,或先 Promise.all 映射后再 await。
现象用 Promise.all 时因一个失败导致全部结果丢失。
原因all 遇到任一 reject 立即 reject,不返回其他已完成的结果。
处置需要保留各自结果时改用 Promise.allSettled。
现象默认参数没生效,值变成了 undefined。
原因显式传了 null 不会触发默认值,只有不传或传 undefined 才触发。
处置用 `x = 1` 形参,或在函数体内用 x ?? 1 处理 null。
现象const 声明的数组 push 报错。
原因误解了 const 语义:它锁定的是引用而非内容。
处置const 数组可以 push(内容可变),只是不能重新赋值给别的数组;要冻结内容用 Object.freeze。
现象reduce 不给初始值时结果变成 NaN 或抛错。
原因空数组时 reduce 会拿第一个元素当初始值,之后运算出错。
处置始终传第二个参数作为初始值,如 reduce((acc, x) => acc + x, 0)。
现象ESM 引入的模块在 Node 里报 Unexpected token export。
原因package.json 未声明 "type": "module",Node 按 CommonJS 解析。
处置设置 "type": "module",或把文件扩展名改为 .mjs;构建产物则交给打包器处理。
排障路径
1确认 this 到底指向谁
const fn = function() { console.log(this) }与箭头函数对照跑一次即可看出差别;对象方法必须用普通函数。
2循环内正确等待异步
for (const x of list) { await handle(x) }for...of 会逐个 await;forEach 不会等,这是最常见的踩坑点。
3需要保留每个结果时改用 allSettled
Promise.allSettled([p1, p2])返回每项的 status 与原因,适合批量任务部分失败仍要继续。
4安全地取可能缺失的键
const { name = "匿名", age } = person解构默认值只在属性为 undefined 时生效,不影响 null。
5reduce 务必带初始值
arr.reduce((acc, x) => acc + x, 0)空数组时不给初始值会出错;显式写 0 最安全。
命令示例
用 map 一次性转换数组
[1, 2, 3].map((x) => x * 2)map 返回一个长度相同的新数组,不改动原数组,适合派生视图数据。
输出
[2, 4, 6]
用解构给字段赋默认值
const user = { name: "alice" }
const { name, age = 18 } = user
console.log(name, age)解构默认值只在属性值严格等于 undefined 时才生效,null 或空字符串不会被替换。
输出
alice 18
async/await 串行读取再处理
async function load() {
const res = await fetch("/api/user")
const data = await res.json()
return data
}await 会把后续逻辑暂挂到 Promise 落定后再继续,外层要用 try/catch 拦下 reject 的错误。
Promise.all 并行等待
const [a, b] = await Promise.all([p1, p2])Promise.all 有一个 reject 就整体 reject;想互不拖累地拿到各自结果用 Promise.allSettled。
常见坑与注意事项
- 箭头函数不绑定自己的 this,若在对象方法或事件回调里需要动态 this 就用 function;否则 this 会泄露到外层作用域。
- const 只禁止重新绑定变量本身,数组 push、对象属性赋值都照常可行,别误以为整个值被冻结不变量。
- 避免使用 var:它有函数作用域与变量提升,容易踩到声明顺序和闭包捕获的坑,一律用 const/let。
- 用 == 会做隐式类型转换(0 == false 相等),判断相等一律用 ===;断言 async 抛错要放在 try/catch 里,别让 reject 变成 unhandledrejection。
提示
- 优先使用 const,只有需要重新赋值时才用 let,避免使用 var。
- 箭头函数没有自己的 this,会捕获上下文的 this,不适合做对象方法。
- async/await 是 Promise 的语法糖,让异步代码看起来像同步,更易读。
常见问题
javascript 的 == 与 === 到底有什么区别?
== 会先做类型转换再比较,比如 '1' == 1 成立、null == undefined 成立,容易产生难以察觉的 bug;=== 要求类型和值都相等,不做隐式转换。业务代码里应一律用 ===,判断空值用 x === null 或 typeof 判断。
var、let、const 该什么时候用?
var 有函数作用域、可重复声明且有变量提升,易致意外;let 和 const 都是块级作用域。默认用 const 声明不重新赋值的变量,确实要改变量值再用 let,尽量不用 var。注意 const 只是禁止重新赋值,对象的属性仍可修改。
javascript 数组的 map 和 forEach 有什么区别?
关键区别是返回值:map 返回一个新数组(结果由每个元素执行回调后的返回值组成),适合做变换;forEach 只执行回调、返回 undefined,适合做打印、计数、修改外部状态这类副作用。需要产出新数组时用 map,仅想遍历时用 forEach。
javascript 里怎么安全地深拷贝一个对象?
浅拷贝(展开运算符 {...obj}、Object.assign)只复制顶层,嵌套对象仍是引用,改动会相互影响。JSON.parse(JSON.stringify(obj)) 能做深拷贝但会丢弃函数、undefined、Date、正则并支持不了循环引用;要保留这些或含循环结构时用 structuredClone(obj)。
async/await 里的错误该怎么捕获?
await 会把 Promise 的 rejection 当作同步异常抛出,因此用 try/catch 包住 await 即可捕获;在顶层(如模块作用域)可加 .catch()。注意一个 await 失败不会自动跳过后续语句,需要决定是让整个函数失败还是捕获后继续执行。
由 巧匠 维护
公开更新于 2026年7月21日,内容持续校对官方文档。