ES6 实用备忘录:核心特性与常用 API 速查
概述
ES6(ECMAScript 2015)是 JavaScript 语言发展史上的里程碑版本——2015 年 6 月正式发布,彻底弥补了 ES5 的语法短板,引入了近 20 项核心新特性(如块级作用域、箭头函数、Promise 等),让 JavaScript 从 “脚本语言” 向 “成熟编程语言” 迈出关键一步。
如今 ES6 已成为前端开发的 “基础语法标准”(所有现代浏览器、Node.js 均全面支持),但它的 API 和特性较多,日常开发中难免需要快速查阅。本文以 “高频实用” 为原则,梳理 ES6 核心特性与常用 API,按 “变量声明”“字符串 / 数组 / 对象”“异步”“数据结构” 等维度分类,既是新手入门的 “语法字典”,也是老手开发的 “速查手册”。
一、变量声明:let /const(替代 var)
ES6 新增 let 和 const 关键字,解决了 var 存在的 “变量提升”“全局污染”“无块级作用域” 三大问题,是现代 JS 变量声明的首选。
关键字 | 核心特性 | 适用场景 | 注意事项 |
---|---|---|---|
let | 1. 块级作用域(仅在 {} 内有效) 2. 不允许重复声明 3. 不存在变量提升(暂存死区) | 声明 “后续会修改” 的变量(如循环变量、状态变量) | 不能在同一作用域内重复声明同一变量(如 let a; let a; 报错) |
const | 1. 同 let 的块级作用域、不重复声明、无变量提升 2. 声明 “只读常量”(赋值后不可修改) | 声明 “后续不修改” 的变量(如配置项、固定值、函数) | 1. 声明时必须初始化(const a; 报错) 2. 若为引用类型(对象 / 数组),仅限制 “地址不可变”,内部属性可修改(如 const obj = {a:1}; obj.a=2; 合法) |
示例:
// let 示例:块级作用域
if (true) {
let a = 10;
console.log(a); // 10(块内有效)
}
console.log(a); // ReferenceError(块外无效)
// const 示例:只读常量
const PI = 3.1415;
PI = 3; // TypeError(基础类型不可修改)
const user = { name: "张三" };
user.name = "李四"; // 合法(引用类型内部属性可改)
user = { name: "王五" }; // TypeError(地址不可改)
二、语法糖:扩展运算符与模板字符串
ES6 提供两个高频语法糖,大幅简化 “数组 / 对象展开” 和 “字符串拼接” 操作。
1. 扩展运算符(...)
将 “可迭代对象”(数组、字符串、Set、Map 等)或 “对象” 展开为独立元素,常用于数组合并、对象拷贝、函数参数传递。
适用场景 | 示例 | 说明 |
---|---|---|
数组展开 | const arr1 = [1,2]; const arr2 = [...arr1, 3,4]; | arr2 结果为 [1,2,3,4],实现数组浅拷贝与合并 |
对象展开 | const obj1 = {a:1}; const obj2 = {...obj1, b:2}; | obj2 结果为 {a:1, b:2},实现对象浅拷贝与属性新增 |
函数参数 | function sum(a,b,c) { return a+b+c; } const arr = [1,2,3]; sum(...arr); | 等价于 sum(1,2,3),将数组元素作为独立参数传递 |
示例:
// 数组合并
const arrA = [1, 2];
const arrB = [3, 4];
const arrMerge = [...arrA, ...arrB]; // [1,2,3,4]
// 对象拷贝(浅拷贝)
const objA = { name: "张三", age: 20 };
const objCopy = { ...objA }; // { name: "张三", age: 20 }
const objUpdate = { ...objA, age: 21 }; // { name: "张三", age: 21 }(覆盖属性)
2. 模板字符串(${})
用反引号()包裹字符串,通过 ${变量 / 表达式}` 嵌入动态内容,解决传统字符串拼接的 “引号嵌套”“换行麻烦” 问题。
核心特性:
- 支持直接嵌入变量或表达式(无需 + 拼接);
- 支持多行字符串(直接换行,无需 \n);
- 支持嵌套模板字符串。
示例:
const name = "张三";
const age = 20;
// 1. 嵌入变量
const str1 = `我叫 ${name},今年 ${age} 岁`;
console.log(str1); // "我叫 张三,今年 20 岁"
// 2. 嵌入表达式
const str2 = `明年我 ${age + 1} 岁`;
console.log(str2); // "明年我 21 岁"
// 3. 多行字符串
const str3 = `
<div>
<p>姓名:${name}</p>
<p>年龄:${age}</p>
</div>
`; // 直接换行,输出保留格式
三、字符串增强:ES6 新增 String API
ES6 为 String 原型新增多个实用方法,替代传统的 indexOf 判断逻辑,代码更易读。
API 方法 | 语法 | 功能说明 | 示例 |
---|---|---|---|
includes() | str.includes(搜索值[, 起始位置]) | 判断字符串是否包含指定值,返回布尔值 | "abc".includes("b") → true |
startsWith() | str.startsWith(搜索值[, 起始位置]) | 判断字符串是否以指定值开头,返回布尔值 | "abc".startsWith("a") → true |
endsWith() | str.endsWith(搜索值[, 长度]) | 判断字符串是否以指定值结尾,返回布尔值 | "abc".endsWith("c") → true |
repeat() | str.repeat(次数) | 将字符串重复指定次数,返回新字符串 | "ab".repeat(3) → "ababab" |
padStart() | str.padStart(目标长度[, 补全字符]) | 从左侧补全字符串至目标长度,默认补空格 | "5".padStart(2, "0") → "05"(常用于日期格式化) |
padEnd() | str.padEnd(目标长度[, 补全字符]) | 从右侧补全字符串至目标长度,默认补空格 | "a".padEnd(3, "b") → "abb" |
indexOf() | str.indexOf(搜索值[, 起始位置]) | 查找指定值在字符串中的首次索引,无则返回 -1(ES5 方法,ES6 中仍常用) | "abc".indexOf("b") → 1 |
实用场景示例:
// 日期格式化(补零)
const day = "5";
const formattedDay = day.padStart(2, "0"); // "05"
// 判断文件类型
const fileName = "report.pdf";
if (fileName.endsWith(".pdf")) {
console.log("是 PDF 文件");
}
// 重复生成分隔线
const line = "-".repeat(50);
console.log(line); // "--------------------------------------------------"
四、数组增强:ES6 新增 Array API
ES6 对数组的增强是核心亮点,新增 “创建方法”“遍历方法”“查找方法” 等,覆盖 90% 数组操作场景。
1. 数组创建方法
API 方法 | 语法 | 功能说明 | 示例 |
---|---|---|---|
Array.from() | Array.from(可迭代对象[, 映射函数]) | 将 “类数组对象”(如 arguments、DOM 集合)或 “可迭代对象”(如 Set)转为真正的数组,支持映射处理 | Array.from([1,2], x => x*2) → [2,4] |
Array.of() | Array.of(元素 1, 元素 2, ...) | 创建包含指定元素的数组,解决 new Array() 的歧义(new Array(2) 是长度 2 的空数组,Array.of(2) 是 [2]) | Array.of(1,2,3) → [1,2,3] |
2. 数组遍历与转换方法
API 方法 | 语法 | 功能说明 | 特点 |
---|---|---|---|
forEach() | arr.forEach((元素, 索引, 数组) => {}) | 遍历数组,对每个元素执行回调,无返回值 | 仅用于遍历,无法中断循环(break 无效) |
map() | arr.map((元素, 索引, 数组) => { return 新元素 }) | 遍历数组,返回由 “回调返回值” 组成的新数组 | 用于 “数组转换”(如将数组元素翻倍、格式转换) |
filter() | arr.filter((元素, 索引, 数组) => { return 布尔值 }) | 遍历数组,返回 “回调返回 true” 的元素组成的新数组 | 用于 “数组筛选”(如过滤偶数、筛选符合条件的对象) |
reduce() | arr.reduce((累加器, 元素, 索引, 数组) => { return 新累加器 }, 初始值) | 从左到右遍历数组,将元素逐步累加到 “累加器”,返回最终结果 | 用途广泛:求和、求最大值、数组转对象、扁平数组等 |
reduceRight() | arr.reduceRight(回调, 初始值) | 同 reduce,但从右到左遍历数组 | 适用于需从尾部开始处理的场景(如倒序累加) |
3. 数组查找方法
API 方法 | 语法 | 功能说明 | 示例 |
---|---|---|---|
find() | arr.find((元素, 索引, 数组) => 布尔值) | 查找数组中 “首个满足条件” 的元素,找到返回元素,否则返回 undefined | [1,2,3].find(x => x>2) → 3 |
findIndex() | arr.findIndex((元素, 索引, 数组) => 布尔值) | 查找数组中 “首个满足条件” 的元素索引,找到返回索引,否则返回 -1 | [1,2,3].findIndex(x => x>2) → 2 |
some() | arr.some((元素, 索引, 数组) => 布尔值) | 判断数组中 “是否存在至少一个” 满足条件的元素,返回布尔值 | [1,2,3].some(x => x>2) → true |
every() | arr.every((元素, 索引, 数组) => 布尔值) | 判断数组中 “所有元素” 是否都满足条件,返回布尔值 | [1,2,3].every(x => x>0) → true |
includes() | arr.includes(查找值[, 起始索引]) | 判断数组是否包含指定值,返回布尔值(比 indexOf 更易读) | [1,2,3].includes(2) → true |
indexOf() | arr.indexOf(查找值[, 起始索引]) | 查找指定值在数组中的首次索引,无则返回 -1(ES5 方法,仍常用) | [1,2,3].indexOf(2) → 1 |
4. 其他实用方法
API 方法 | 语法 | 功能说明 | 示例 |
---|---|---|---|
fill() | arr.fill(填充值[, 起始索引[, 结束索引]]) | 用指定值填充数组的指定范围,返回修改后的原数组 | [1,2,3].fill(0, 1, 3) → [1,0,0] |
keys() | arr.keys() | 返回数组 “索引” 的迭代器,可通过 Array.from() 转为索引数组 | Array.from([1,2,3].keys()) → [0,1,2] |
values() | arr.values() | 返回数组 “元素” 的迭代器,可通过 Array.from() 转为元素数组 | Array.from([1,2,3].values()) → [1,2,3] |
entries() | arr.entries() | 返回数组 “[索引,元素]” 的迭代器,可用于同时遍历索引和元素 | Array.from([1,2,3].entries()) → [[0,1], [1,2], [2,3]] |
高频示例:
// 1. map:数组元素翻倍
const arr = [1, 2, 3];
const doubled = arr.map((x) => x * 2); // [2,4,6]
// 2. filter:筛选偶数
const even = arr.filter((x) => x % 2 === 0); // [2]
// 3. reduce:数组求和
const sum = arr.reduce((acc, cur) => acc + cur, 0); // 6
// 4. find:查找大于 2 的元素
const found = arr.find((x) => x > 2); // 3
// 5. includes:判断是否包含 2
const hasTwo = arr.includes(2); // true
五、循环增强:for...of 与 for...in(遍历优化)
ES6 新增 for...of 循环,弥补 for...in 和 forEach 的不足,支持遍历 “可迭代对象”(数组、字符串、Set、Map、Generator 等)。
循环类型 | 语法 | 遍历对象 | 核心特点 | 适用场景 |
---|---|---|---|---|
for...of | for (const 元素 of 可迭代对象) {} | 数组、字符串、Set、Map、NodeList 等 | 1. 直接遍历 “元素值”,无需通过索引访问 2. 支持 break/continue 中断循环 | 遍历 “元素值”(如数组元素、字符串字符) |
for...in | for (const 键名 in 对象) {} | 对象(普通对象、数组) | 1. 遍历对象的 “可枚举属性”(包括原型链上的属性) 2. 遍历数组时,键名为字符串类型的索引(如 "0") | 遍历 “对象属性名”(不推荐遍历数组,易受原型链影响) |
示例:
// for...of 遍历数组
const arr = [1, 2, 3];
for (const item of arr) {
if (item === 2) break; // 支持 break 中断
console.log(item); // 1(仅输出第一个元素)
}
// for...of 遍历字符串
const str = "abc";
for (const char of str) {
console.log(char); // a → b → c
}
// for...in 遍历对象
const obj = { name: "张三", age: 20 };
for (const key in obj) {
// 推荐加 hasOwnProperty 过滤原型链属性
if (obj.hasOwnProperty(key)) {
console.log(`${key}: ${obj[key]}`); // name: 张三 → age: 20
}
}
六、对象增强:ES6 新增 Object API
ES6 为 Object 构造函数新增多个静态方法,简化 “对象比较”“对象拷贝”“属性遍历” 操作。
API 方法 | 语法 | 功能说明 | 示例 |
---|---|---|---|
Object.is() | Object.is(值 1, 值 2) | 判断两个值是否 “严格相等”,修复 === 的两个缺陷(NaN === NaN 为 false,+0 === -0 为 true) | Object.is(NaN, NaN) → true;Object.is(+0, -0) → false |
Object.assign() | Object.assign(目标对象, 源对象 1, 源对象 2, ...) | 将多个源对象的 “可枚举属性” 复制到目标对象,返回目标对象(浅拷贝) | Object.assign({a:1}, {b:2}) → {a:1, b:2} |
Object.keys() | Object.keys(对象) | 返回对象的 “所有可枚举属性名”(数组) | Object.keys({a:1, b:2}) → ["a", "b"] |
Object.entries() | Object.entries(对象) | 返回对象的 “所有可枚举属性名值对”(数组) | Object.entries({a:1, b:2}) → [["a", 1], ["b", 2]] |
Object.values() | Object.values(对象) | 返回对象的 “所有可枚举属性值”(数组) | Object.values({a:1, b:2}) → [1, 2] |