JavaScript ES6 特性详解教程:从入门到精通
引言:为什么你需要掌握ES6?
还在为JavaScript的变量提升、作用域混乱而头疼吗?还在使用繁琐的function关键字和var声明吗?ES6(ECMAScript 2015)作为JavaScript语言的革命性更新,带来了超过20项重要新特性,彻底改变了JavaScript的开发范式。
本文将为你全面解析ES6的核心特性,通过丰富的代码示例、对比表格和流程图,帮助你快速掌握现代JavaScript开发的核心技能。读完本文,你将能够:
- ✅ 熟练使用箭头函数、解构赋值等语法糖
- ✅ 掌握Class、Module等面向对象编程特性
- ✅ 理解Promise、Generator等异步编程方案
- ✅ 运用Map、Set等高效数据结构
- ✅ 掌握模板字符串、默认参数等实用特性
ES6特性全景图
一、箭头函数(Arrows):告别function关键字
基本语法对比
| ES5写法 | ES6箭头函数 | 说明 |
|---|---|---|
function(x) { return x + 1; } | x => x + 1 | 单参数单表达式 |
function(x, y) { return x + y; } | (x, y) => x + y | 多参数单表达式 |
function(x) { return { value: x }; } | x => ({ value: x }) | 返回对象字面量 |
实际应用场景
// 1. 数组操作
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(n => n * 2); // [2, 4, 6, 8, 10]
// 2. 事件处理
document.getElementById('btn').addEventListener('click', () => {
console.log('Button clicked!');
});
// 3. this绑定(重要特性)
const obj = {
name: 'ES6',
tasks: ['learn', 'practice', 'master'],
showTasks() {
this.tasks.forEach(task => {
console.log(`${this.name}: ${task}`);
// 箭头函数自动绑定外层this
});
}
};
注意事项
// 错误用法:箭头函数没有自己的arguments对象
const func = () => {
console.log(arguments); // ReferenceError
};
// 正确用法:使用rest参数
const correctFunc = (...args) => {
console.log(args);
};
二、Class类:真正的面向对象编程
Class语法详解
// ES5原型继承
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
console.log(this.name + ' makes a noise.');
};
// ES6 Class语法
class Animal {
constructor(name) {
this.name = name;
}
// 实例方法
speak() {
console.log(`${this.name} makes a noise.`);
}
// 静态方法
static isAnimal(obj) {
return obj instanceof Animal;
}
// Getter/Setter
get description() {
return `This is ${this.name}`;
}
set nickname(value) {
this._nickname = value;
}
}
继承与多态
class Dog extends Animal {
constructor(name, breed) {
super(name); // 必须调用super()
this.breed = breed;
}
speak() {
super.speak(); // 调用父类方法
console.log(`${this.name} barks.`);
}
// 重写静态方法
static isAnimal(obj) {
return obj instanceof Dog;
}
}
const myDog = new Dog('Rex', 'German Shepherd');
myDog.speak(); // Rex makes a noise. Rex barks.
三、解构赋值(Destructuring):优雅的数据提取
数组解构
// 基本解构
const [first, second, third] = [1, 2, 3];
console.log(first, second, third); // 1 2 3
// 跳过元素
const [a, , c] = [1, 2, 3]; // a=1, c=3
// 默认值
const [x = 1, y = 2] = []; // x=1, y=2
// 剩余元素
const [head, ...tail] = [1, 2, 3, 4]; // head=1, tail=[2,3,4]
对象解构
const person = {
name: 'Alice',
age: 25,
address: {
city: 'Beijing',
country: 'China'
}
};
// 基本解构
const { name, age } = person;
// 重命名
const { name: personName, age: personAge } = person;
// 嵌套解构
const { address: { city, country } } = person;
// 默认值
const { name, age, gender = 'unknown' } = person;
// 函数参数解构
function greet({ name, age }) {
return `Hello, ${name}! You are ${age} years old.`;
}
四、模板字符串(Template Strings):强大的字符串处理
基础用法
const name = 'Bob';
const age = 30;
// ES5字符串拼接
const es5Str = 'Hello, ' + name + '! You are ' + age + ' years old.';
// ES6模板字符串
const es6Str = `Hello, ${name}! You are ${age} years old.`;
// 多行字符串
const multiLine = `
This is a
multi-line
string.
`;
// 表达式计算
const calculation = `2 + 3 = ${2 + 3}`; // "2 + 3 = 5"
标签模板(Tagged Templates)
function highlight(strings, ...values) {
return strings.reduce((result, str, i) => {
return result + str + (values[i] ? `<mark>${values[i]}</mark>` : '');
}, '');
}
const name = 'Alice';
const age = 25;
const message = highlight`Hello, ${name}! You are ${age} years old.`;
// 结果: "Hello, <mark>Alice</mark>! You are <mark>25</mark> years old."
五、let和const:块级作用域的革命
作用域对比表
| 特性 | var | let | const |
|---|---|---|---|
| 作用域 | 函数作用域 | 块级作用域 | 块级作用域 |
| 变量提升 | ✅ | ❌(暂时性死区) | ❌(暂时性死区) |
| 重复声明 | ✅ | ❌ | ❌ |
| 重新赋值 | ✅ | ✅ | ❌ |
实际应用示例
// 1. 循环中的变量作用域
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100); // 输出3次3
}
for (let j = 0; j < 3; j++) {
setTimeout(() => console.log(j), 100); // 输出0,1,2
}
// 2. 常量声明
const PI = 3.14159;
// PI = 3.14; // TypeError: Assignment to constant variable
// 3. 对象常量(属性可修改)
const person = { name: 'Alice' };
person.name = 'Bob'; // ✅ 允许
// person = {}; // ❌ 不允许
六、Promise:异步编程的新范式
Promise基础
// 创建Promise
const fetchData = new Promise((resolve, reject) => {
setTimeout(() => {
const success = Math.random() > 0.3;
if (success) {
resolve({ data: 'Success!' });
} else {
reject(new Error('Failed!'));
}
}, 1000);
});
// 使用Promise
fetchData
.then(result => {
console.log('成功:', result.data);
return processData(result);
})
.then(processed => {
console.log('处理完成:', processed);
})
.catch(error => {
console.error('错误:', error.message);
})
.finally(() => {
console.log('请求完成');
});
Promise实用方法
// Promise.all - 所有Promise都成功
Promise.all([promise1, promise2, promise3])
.then(results => {
console.log('所有任务完成:', results);
})
.catch(error => {
console.error('有一个任务失败:', error);
});
// Promise.race - 第一个完成(成功或失败)
Promise.race([promise1, promise2])
.then(result => {
console.log('第一个完成的任务:', result);
});
// Promise.allSettled - 所有Promise都完成(无论成功失败)
Promise.allSettled([promise1, promise2])
.then(results => {
results.forEach(result => {
if (result.status === 'fulfilled') {
console.log('成功:', result.value);
} else {
console.log('失败:', result.reason);
}
});
});
七、模块化(Modules):代码组织的新方式
导出模块
// math.js - 命名导出
export const PI = 3.14159;
export function sum(a, b) {
return a + b;
}
export function multiply(a, b) {
return a * b;
}
// 或者统一导出
const PI = 3.14159;
function sum(a, b) { return a + b; }
function multiply(a, b) { return a * b; }
export { PI, sum, multiply };
// default导出
export default class Calculator {
// class implementation
}
导入模块
// 命名导入
import { PI, sum } from './math.js';
// 重命名导入
import { sum as add } from './math.js';
// 全部导入
import * as math from './math.js';
// default导入
import Calculator from './calculator.js';
// 混合导入
import Calculator, { PI } from './math.js';
八、Map和Set:高效的数据结构
Map vs Object 对比表
| 特性 | Map | Object |
|---|---|---|
| 键类型 | 任意类型 | String或Symbol |
| 键顺序 | 插入顺序 | 不一定 |
| 大小获取 | map.size | 手动计算 |
| 性能 | 频繁增删时更好 | 一般情况 |
| 序列化 | 需要转换 | 原生支持 |
实际应用
// Map示例
const userMap = new Map();
userMap.set('user1', { name: 'Alice', age: 25 });
userMap.set(123, { name: 'Bob', age: 30 });
console.log(userMap.get('user1')); // {name: "Alice", age: 25}
console.log(userMap.has(123)); // true
console.log(userMap.size); // 2
// Set示例(去重神器)
const numbers = [1, 2, 2, 3, 4, 4, 5];
const uniqueNumbers = [...new Set(numbers)]; // [1, 2, 3, 4, 5]
// 数组去重函数
function removeDuplicates(array) {
return [...new Set(array)];
}
九、增强的对象字面量
const name = 'Alice';
const age = 25;
// ES6增强对象字面量
const person = {
// 属性简写
name,
age,
// 方法简写
greet() {
return `Hello, ${this.name}!`;
},
// 计算属性名
['prop_' + (() => 42)()]: 'computed',
// __proto__设置
__proto__: someProtoObject,
// super调用
toString() {
return 'Person: ' + super.toString();
}
};
十、迭代器和生成器
迭代器模式
// 自定义可迭代对象
const myIterable = {
[Symbol.iterator]() {
let step = 0;
return {
next() {
step++;
if (step <= 3) {
return { value: step, done: false };
}
return { value: undefined, done: true };
}
};
}
};
for (const value of myIterable) {
console.log(value); // 1, 2, 3
}
生成器函数
function* numberGenerator() {
yield 1;
yield 2;
yield 3;
}
const generator = numberGenerator();
console.log(generator.next()); // {value: 1, done: false}
console.log(generator.next()); // {value: 2, done: false}
console.log(generator.next()); // {value: 3, done: false}
console.log(generator.next()); // {value: undefined, done: true}
// 无限生成器
function* infiniteSequence() {
let i = 0;
while (true) {
yield i++;
}
}
十一、ES6新API大全
数组新增方法
// Array.from - 类数组转数组
const arrayLike = { 0: 'a', 1: 'b', length: 2 };
const realArray = Array.from(arrayLike); // ['a', 'b']
// Array.of - 创建数组
Array.of(1, 2, 3); // [1, 2, 3]
// find/findIndex - 查找元素
[1, 5, 10, 15].find(x => x > 8); // 10
[1, 5, 10, 15].findIndex(x => x > 8); // 2
// fill - 填充数组
new Array(3).fill(7); // [7, 7, 7]
// includes - 包含检查
[1, 2, 3].includes(2); // true
字符串新增方法
// includes/startsWith/endsWith
'hello'.includes('ell'); // true
'hello'.startsWith('he'); // true
'hello'.endsWith('lo'); // true
// repeat
'abc'.repeat(3); // 'abcabcabc'
// padStart/padEnd
'5'.padStart(3, '0'); // '005'
'hi'.padEnd(5, '!'); // 'hi!!!'
十二、实战应用:综合案例
案例1:用户数据处理
// 模拟API返回数据
const apiResponse = {
users: [
{ id: 1, name: 'Alice', age: 25, active: true },
{ id: 2, name: 'Bob', age: 30, active: false },
{ id: 3, name: 'Charlie', age: 35, active: true }
],
metadata: {
page: 1,
total: 3
}
};
// 使用ES6特性处理数据
const { users, metadata } = apiResponse;
// 1. 过滤活跃用户
const activeUsers = users.filter(({ active }) => active);
// 2. 提取用户名和年龄
const userInfo = activeUsers.map(({ name, age }) => ({
name,
age,
description: `${name} is ${age} years old`
}));
// 3. 年龄统计
const ageStats = userInfo.reduce((stats, { age }) => {
stats.total += age;
stats.count++;
stats.average = stats.total / stats.count;
return stats;
}, { total: 0, count: 0, average: 0 });
console.log(userInfo);
console.log(ageStats);
案例2:Promise链式操作
class DataService {
constructor() {
this.cache = new Map();
}
async fetchUserData(userId) {
// 检查缓存
if (this.cache.has(userId)) {
return this.cache.get(userId);
}
try {
// 模拟API请求
const userData = await this.mockApiCall(`/users/${userId}`);
const posts = await this.mockApiCall(`/users/${userId}/posts`);
// 处理数据
const result = {
...userData,
posts: posts.slice(0, 5), // 只取前5篇文章
lastUpdated: new Date().toISOString()
};
// 缓存结果
this.cache.set(userId, result);
return result;
} catch (error) {
console.error('获取用户数据失败:', error);
throw new Error('无法获取用户数据');
}
}
async mockApiCall(url) {
return new Promise((resolve) => {
setTimeout(() => {
// 模拟API响应
const responses = {
'/users/1': { id: 1, name: 'Alice', email: 'alice@example.com' },
'/users/1/posts': [{ id: 1, title: 'Post 1' }, { id: 2, title: 'Post 2' }]
};
resolve(responses[url] || {});
}, 500);
});
}
}
// 使用示例
const service = new DataService();
service.fetchUserData(1)
.then(data => console.log('用户数据:', data))
.catch(error => console.error('错误:', error));
十三、ES6学习路线图
flowchart TD
A[ES6学习路线] --> B[基础语法
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



