ES6(ECMAScript 2015)是 JavaScript 语言的一次重大升级,引入了大量实用特性,彻底改变了 JS 的开发模式。以下是其核心新特性的详细解析,结合用法和场景说明:
一、变量声明:let / const(替代 var)
解决 var 的变量提升、函数级作用域、重复声明三大问题,引入块级作用域({} 内有效)。
let:- 块级作用域,仅在声明的代码块内有效(循环、条件、函数体等)。
- 不存在变量提升(暂时性死区 TDZ:声明前访问会报错)。
- 不可重复声明。
if (true) { let x = 10; console.log(x); // 10 } console.log(x); // ReferenceError: x is not defined(块级作用域隔离)const:- 与
let特性一致(块级、无提升、不可重复声明)。 - 声明常量,必须初始化,且不能重新赋值(但引用类型的内容可修改)。
const PI = 3.14; PI = 3.1415; // TypeError: Assignment to constant variable. const obj = { name: "ES6" }; obj.name = "ECMAScript 2015"; // 允许(仅禁止重新赋值引用地址)- 与
- 最佳实践:优先用
const,需要修改时用let,杜绝var。
二、箭头函数(Arrow Functions)
简化函数语法,解决 this 绑定问题。
- 语法:
(参数) => 表达式或(参数) => { 代码块 }- 单个参数可省略括号:
x => x * 2。 - 无参数或多个参数需加括号:
() => 1或(a, b) => a + b。 - 表达式返回值可省略
return;代码块需显式写return。
- 单个参数可省略括号:
- 核心特性:
- 无自己的
this:继承外层作用域的this(固定绑定,不会随调用方式改变)。 - 不能作为构造函数(不能用
new调用)。 - 没有
arguments对象(需用剩余参数替代)。
- 无自己的
- 场景:回调函数(如
map、forEach、Promise),避免this指向混乱。
// 简化数组遍历
const arr = [1, 2, 3];
const doubled = arr.map(x => x * 2); // [2,4,6]
// 解决 this 绑定问题(传统函数需用 bind 或 var self = this)
const person = {
name: "张三",
sayHi: function() {
setTimeout(() => {
console.log(`Hi, ${this.name}`); // 继承 person 的 this,输出 "Hi, 张三"
}, 1000);
}
};
三、模板字符串(Template Literals)
替代字符串拼接,支持多行字符串和变量插值。
- 语法:用反引号
`包裹,变量 / 表达式用${}嵌入。 - 特性:
- 原生支持多行字符串(无需
\n)。 - 直接嵌入变量、表达式(甚至函数调用)。
- 原生支持多行字符串(无需
const name = "李四";
const age = 25;
// 变量插值
const info = `姓名:${name},年龄:${age + 5}`; // "姓名:李四,年龄:30"
// 多行字符串
const html = `
<div>
<p>${name}</p>
</div>
`;
四、解构赋值(Destructuring Assignment)
快速从数组 / 对象中提取数据,简化代码。
- 数组解构:按顺序匹配,支持默认值、剩余参数。
const [a, b, c = 3] = [1, 2]; // a=1, b=2, c=3
const [x, ...rest] = [1, 2, 3, 4]; // x=1, rest=[2,3,4]
- 对象解构:按属性名匹配,支持别名、默认值。
const user = { name: "王五", age: 30 };
const { name: username, age } = user; // username="王五", age=30
const { gender = "男" } = user; // gender="男"(默认值)
- 场景:函数参数接收、对象 / 数组数据提取、交换变量(
[a, b] = [b, a])。
五、扩展运算符(Spread Operator)
... 用于展开数组 / 对象,或收集剩余参数,灵活处理数据。
- 展开数组:合并数组、传递函数参数。
const arr1 = [1, 2];
const arr2 = [3, 4];
const merged = [...arr1, ...arr2]; // [1,2,3,4]
function sum(a, b, c) { return a + b + c; }
sum(...[1, 2, 3]); // 6(等价于 sum(1,2,3))
- 展开对象:合并对象(后面的属性覆盖前面的)。
const obj1 = { a: 1 };
const obj2 = { b: 2, a: 3 };
const mergedObj = { ...obj1, ...obj2 }; // { a:3, b:2 }
- 注意:数组展开是浅拷贝,对象展开仅拷贝自身可枚举属性(不包含原型链)。
六、剩余参数(Rest Parameters)
... 用于收集函数的剩余参数,替代 arguments。
- 语法:
function fn(a, b, ...rest) {} - 特性:
- 必须是函数最后一个参数。
- 返回数组(
arguments是类数组对象,需转换)。
function sum(...nums) {
return nums.reduce((total, num) => total + num, 0);
}
sum(1, 2, 3); // 6(nums = [1,2,3])
七、对象新增特性
1. 对象字面量简化
- 属性简写:属性名与变量名一致时,可省略
: 变量。 - 方法简写:省略
function关键字。 - 计算属性名:用
[]嵌入表达式作为属性名。
const name = "赵六";
const age = 35;
const person = {
name, // 简写:等价于 name: name
age,
sayHi() { // 方法简写:等价于 sayHi: function() {}
console.log(`Hi, ${this.name}`);
},
[`prop_${1 + 2}`]: "计算属性" // 计算属性名:prop_3: "计算属性"
};
2. Object.assign()
用于合并对象,将源对象的属性复制到目标对象(浅拷贝)。
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2); // target = { a:1, b:2, c:3 }
八、数组新增方法
ES6 为数组新增了多个实用方法,简化遍历、过滤、转换等操作:
Array.from():将类数组对象(如arguments、DOM 集合)或可迭代对象(如字符串)转为数组。const str = "abc"; Array.from(str); // ["a", "b", "c"] const divs = document.querySelectorAll("div"); Array.from(divs).forEach(div => console.log(div));Array.of():创建数组(解决new Array(2)歧义:Array.of(2)是[2],new Array(2)是长度为 2 的空数组)。- 实例方法:
find():返回第一个满足条件的元素(无则undefined)。findIndex():返回第一个满足条件的元素索引(无则-1)。includes():判断数组是否包含指定值(返回布尔值,支持 NaN)。
const arr = [1, 2, 3, NaN]; arr.find(x => x > 2); // 3 arr.findIndex(x => x === 2); // 1 arr.includes(NaN); // true(传统 indexOf 无法识别 NaN)
九、Promise:异步编程的标准方案
解决回调地狱( Callback Hell ),统一异步代码的写法,支持链式调用。
- 核心概念:
Promise是一个对象,代表异步操作的最终完成(或失败)及结果值。- 三种状态:
pending(进行中)、fulfilled(成功)、rejected(失败),状态一旦改变不可逆。
- 语法:
const promise = new Promise((resolve, reject) => { // 异步操作(如请求接口、定时器) setTimeout(() => { const success = true; if (success) { resolve("操作成功"); // 成功时调用,传递结果 } else { reject("操作失败"); // 失败时调用,传递错误 } }, 1000); }); // 链式调用:成功用 then,失败用 catch promise.then(res => console.log(res)) // 1 秒后输出 "操作成功" .catch(err => console.log(err)); - 常用方法:
Promise.all([p1, p2]):所有 Promise 成功才返回,有一个失败则立即失败。Promise.race([p1, p2]):第一个完成的 Promise 决定结果(无论成功 / 失败)。
- 场景:异步请求、文件操作等需要等待结果的操作。
十、Class:面向对象编程的语法糖
ES6 引入 class 关键字,简化传统原型链继承的写法,使面向对象更直观(本质仍是原型继承)。
- 基础语法:
// 定义类 class Person { // 构造函数(实例化时执行) constructor(name, age) { this.name = name; this.age = age; } // 实例方法(原型上的方法) sayHi() { console.log(`Hi, ${this.name}`); } // 静态方法(类上的方法,用 static 修饰) static create(name, age) { return new Person(name, age); } } // 实例化 const person = new Person("孙七", 40); person.sayHi(); // "Hi, 孙七" // 调用静态方法 const person2 = Person.create("周八", 45); - 继承:用
extends实现类继承,super()调用父类构造函数。class Student extends Person { constructor(name, age, score) { super(name, age); // 必须先调用父类构造函数 this.score = score; } showScore() { console.log(`${this.name} 的分数:${this.score}`); } } const student = new Student("吴九", 20, 90); student.sayHi(); // 继承父类方法:"Hi, 吴九" student.showScore(); // 子类方法:"吴九 的分数:90"
十一、Module:模块化系统
ES6 原生支持模块化,允许将代码拆分为多个文件(模块),通过 import/export 导入导出,解决全局变量污染、依赖管理问题。
- 导出(export):
- 命名导出:导出多个变量 / 函数(可多个)。
- 默认导出:导出单个变量 / 函数 / 类(每个模块只能有一个)。
// module.js export const a = 1; // 命名导出 export function sum(x, y) { return x + y; } // 命名导出 const b = 2; export default b; // 默认导出 - 导入(import):
- 命名导入:需与导出名称一致,可用
as重命名。 - 默认导入:可自定义名称,无需大括号。
// main.js import { a, sum as add } from './module.js'; // 命名导入(sum 重名为 add) import b from './module.js'; // 默认导入 console.log(a); // 1 console.log(add(1, 2)); // 3 console.log(b); // 2 - 命名导入:需与导出名称一致,可用
- 场景:大型项目代码拆分、第三方库引入(如 React、Vue)。
十二、其他重要特性
- 默认参数(Default Parameters):函数参数可设置默认值。
function greet(name = "陌生人") { console.log(`Hello, ${name}`); } greet(); // "Hello, 陌生人" - Set / Map:新的数据结构:
Set:无重复元素的集合,支持add()、delete()、has()等方法(常用于去重)。const set = new Set([1, 2, 2, 3]); set.size; // 3(自动去重) [...set]; // [1,2,3](转为数组)Map:键值对集合,键可以是任意类型(对象、函数等,解决对象键只能是字符串 / Symbol 的限制)。const map = new Map(); const obj = {}; map.set(obj, "value"); // 键为对象 map.get(obj); // "value"
- Symbol:唯一标识符:
- 生成唯一值,用于对象的唯一属性名(避免属性冲突)。
const key = Symbol("key"); const obj = { [key]: "唯一值" }; console.log(obj[key]); // "唯一值" - for...of 循环:遍历可迭代对象(数组、Set、Map、字符串等),替代
for/forEach,支持break/continue。const arr = [1, 2, 3]; for (const item of arr) { if (item === 2) break; console.log(item); // 1 }
总结
ES6 的核心价值是简化语法、提升代码可读性、解决历史遗留问题(如 this 绑定、回调地狱)、支持模块化和面向对象,成为现代 JavaScript 开发的基础。以上特性中,let/const、箭头函数、模板字符串、解构赋值、扩展运算符、Promise、Module 是日常开发中最常用的,掌握这些特性能大幅提升开发效率。

473

被折叠的 条评论
为什么被折叠?



