主题
进阶练习
欢迎来到JavaScript进阶练习!这些练习将帮助你掌握更复杂的JavaScript概念和现代开发技巧。
🚀 ES6+ 特性
练习 1.1: 解构赋值
javascript
// 练习:掌握数组和对象解构
// 1. 数组解构
const colors = ['红色', '绿色', '蓝色', '黄色', '紫色'];
// 使用解构赋值获取前三个颜色和剩余颜色
// 你的代码:
const [first, second, third, ...rest] = colors;
// 2. 对象解构
const user = {
id: 1,
name: '张三',
email: 'zhangsan@example.com',
address: {
city: '北京',
district: '朝阳区'
},
hobbies: ['读书', '游泳', '编程']
};
// 使用解构赋值提取用户信息,并重命名某些属性
// 你的代码:
// 3. 函数参数解构
function createUserProfile({name, age, email, city = '未知'}) {
// 你的代码:返回格式化的用户资料
}
// 测试
console.log(createUserProfile({
name: '李四',
age: 28,
email: 'lisi@example.com'
}));
练习 1.2: 模板字符串和标签模板
javascript
// 练习:模板字符串的高级用法
// 1. 多行字符串和表达式插值
function generateHTML(title, content, author) {
// 你的代码:使用模板字符串生成HTML
return `
<!-- 生成包含标题、内容和作者的HTML结构 -->
`;
}
// 2. 标签模板函数
function highlight(strings, ...values) {
// 你的代码:创建一个标签模板函数
// 将插值部分用<mark>标签包围
}
// 使用标签模板
const name = '小明';
const score = 95;
const result = highlight`学生 ${name} 的成绩是 ${score} 分`;
console.log(result);
// 3. 条件模板
function createMessage(user, isVIP) {
// 你的代码:根据VIP状态生成不同的欢迎消息
}
练习 1.3: 箭头函数和作用域
javascript
// 练习:理解箭头函数的this绑定
const team = {
name: '开发团队',
members: ['小明', '小红', '小刚'],
// 1. 使用箭头函数保持this绑定
showMembers: function() {
// 你的代码:使用箭头函数遍历members
// 确保this指向team对象
},
// 2. 延迟执行
delayedGreeting: function() {
// 你的代码:使用setTimeout和箭头函数
// 2秒后输出团队问候语
},
// 3. 数组方法中的箭头函数
getFormattedMembers: function() {
// 你的代码:使用map和箭头函数
// 返回格式化的成员列表
}
};
team.showMembers();
team.delayedGreeting();
console.log(team.getFormattedMembers());
🔄 异步编程
练习 2.1: Promise 基础
javascript
// 练习:创建和使用Promise
// 1. 创建一个模拟API请求的Promise
function fetchUserData(userId) {
return new Promise((resolve, reject) => {
// 你的代码:
// 模拟网络延迟(1-3秒随机)
// 70%概率成功返回用户数据
// 30%概率失败返回错误信息
});
}
// 2. 使用Promise处理结果
function getUserInfo(userId) {
// 你的代码:
// 调用fetchUserData并处理成功/失败情况
}
// 3. Promise链式调用
function processUserData(userId) {
// 你的代码:
// 获取用户数据 -> 验证数据 -> 格式化数据 -> 保存数据
// 使用Promise链式调用
}
// 测试
getUserInfo(123);
processUserData(456);
练习 2.2: async/await
javascript
// 练习:使用async/await简化异步代码
// 1. 将Promise代码转换为async/await
async function getUserInfoAsync(userId) {
try {
// 你的代码:使用async/await重写getUserInfo函数
} catch (error) {
// 错误处理
}
}
// 2. 并行异步操作
async function fetchMultipleUsers(userIds) {
// 你的代码:
// 同时获取多个用户的数据
// 使用Promise.all优化性能
}
// 3. 顺序异步操作
async function processUsersSequentially(userIds) {
// 你的代码:
// 按顺序处理用户数据
// 每个用户处理完成后再处理下一个
}
// 4. 异步迭代器
async function* userDataGenerator(userIds) {
// 你的代码:
// 创建异步生成器,逐个yield用户数据
}
// 测试
(async () => {
await getUserInfoAsync(123);
const users = await fetchMultipleUsers([1, 2, 3, 4, 5]);
console.log(users);
for await (const user of userDataGenerator([1, 2, 3])) {
console.log('处理用户:', user);
}
})();
练习 2.3: 错误处理和重试机制
javascript
// 练习:实现健壮的异步错误处理
// 1. 带重试的异步函数
async function fetchWithRetry(url, maxRetries = 3) {
// 你的代码:
// 实现自动重试机制
// 指数退避算法(每次重试间隔翻倍)
}
// 2. 超时控制
function withTimeout(promise, timeoutMs) {
// 你的代码:
// 为Promise添加超时控制
// 超时后自动reject
}
// 3. 批量操作错误处理
async function batchProcess(items, processor, { concurrency = 3, continueOnError = true } = {}) {
// 你的代码:
// 批量处理数据,控制并发数
// 可选择是否在错误时继续处理其他项目
}
// 测试
(async () => {
try {
const result = await fetchWithRetry('https://api.example.com/data');
console.log(result);
} catch (error) {
console.error('最终失败:', error);
}
})();
🏗️ 面向对象编程
练习 3.1: 类和继承
javascript
// 练习:ES6类语法和继承
// 1. 基础类定义
class Animal {
constructor(name, species) {
// 你的代码:
}
// 实例方法
speak() {
// 你的代码:
}
// 静态方法
static getKingdom() {
// 你的代码:
}
// getter和setter
get info() {
// 你的代码:
}
set name(newName) {
// 你的代码:
}
}
// 2. 继承
class Dog extends Animal {
constructor(name, breed) {
// 你的代码:调用父类构造函数
}
// 重写父类方法
speak() {
// 你的代码:
}
// 新增方法
fetch() {
// 你的代码:
}
}
// 3. 抽象类模拟
class Shape {
constructor() {
if (this.constructor === Shape) {
throw new Error('不能直接实例化抽象类');
}
}
// 抽象方法
getArea() {
throw new Error('子类必须实现getArea方法');
}
}
class Circle extends Shape {
constructor(radius) {
// 你的代码:
}
getArea() {
// 你的代码:
}
}
// 测试
const dog = new Dog('旺财', '金毛');
console.log(dog.speak());
console.log(dog.info);
const circle = new Circle(5);
console.log('圆的面积:', circle.getArea());
练习 3.2: 设计模式
javascript
// 练习:常用设计模式实现
// 1. 单例模式
class DatabaseConnection {
constructor() {
// 你的代码:实现单例模式
// 确保只能创建一个实例
}
static getInstance() {
// 你的代码:
}
connect() {
// 你的代码:
}
}
// 2. 观察者模式
class EventEmitter {
constructor() {
this.events = {};
}
on(event, callback) {
// 你的代码:注册事件监听器
}
emit(event, data) {
// 你的代码:触发事件
}
off(event, callback) {
// 你的代码:移除事件监听器
}
}
// 3. 工厂模式
class ShapeFactory {
static createShape(type, ...args) {
// 你的代码:
// 根据type创建不同的形状对象
// 支持 'circle', 'rectangle', 'triangle'
}
}
// 4. 装饰器模式
function logger(target, propertyKey, descriptor) {
// 你的代码:
// 创建一个方法装饰器,记录方法调用
}
class Calculator {
@logger
add(a, b) {
return a + b;
}
@logger
multiply(a, b) {
return a * b;
}
}
// 测试设计模式
const db1 = DatabaseConnection.getInstance();
const db2 = DatabaseConnection.getInstance();
console.log(db1 === db2); // 应该是true
const emitter = new EventEmitter();
emitter.on('test', (data) => console.log('收到数据:', data));
emitter.emit('test', '哈喽世界');
🔧 高级函数技巧
练习 4.1: 高阶函数
javascript
// 练习:创建和使用高阶函数
// 1. 函数组合
function compose(...functions) {
// 你的代码:
// 实现函数组合,从右到左执行
}
// 2. 柯里化
function curry(fn) {
// 你的代码:
// 实现函数柯里化
}
// 3. 防抖和节流
function debounce(func, delay) {
// 你的代码:
// 实现防抖函数
}
function throttle(func, limit) {
// 你的代码:
// 实现节流函数
}
// 4. 记忆化
function memoize(fn) {
// 你的代码:
// 实现函数记忆化,缓存计算结果
}
// 测试高阶函数
const add = (a, b) => a + b;
const multiply = (a, b) => a * b;
const square = (x) => x * x;
const addThenSquare = compose(square, add);
console.log(addThenSquare(3, 4)); // (3+4)² = 49
const curriedAdd = curry(add);
const add5 = curriedAdd(5);
console.log(add5(3)); // 8
// 斐波那契数列(记忆化优化)
const fibonacci = memoize(function(n) {
if (n < 2) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
});
console.log(fibonacci(40)); // 快速计算
练习 4.2: 函数式编程
javascript
// 练习:函数式编程范式
// 1. 纯函数和不可变性
const users = [
{id: 1, name: '张三', age: 25, active: true},
{id: 2, name: '李四', age: 30, active: false},
{id: 3, name: '王五', age: 35, active: true}
];
// 纯函数:更新用户状态(不修改原数组)
function updateUserStatus(users, userId, active) {
// 你的代码:
// 返回新数组,不修改原数组
}
// 2. 函数管道
function pipe(...functions) {
// 你的代码:
// 实现函数管道,从左到右执行
}
// 使用管道处理数据
const processUsers = pipe(
users => users.filter(user => user.active),
users => users.map(user => ({...user, displayName: `${user.name} (${user.age}岁)`})),
users => users.sort((a, b) => a.age - b.age)
);
console.log(processUsers(users));
// 3. 函子(Functor)
class Maybe {
constructor(value) {
this.value = value;
}
static of(value) {
return new Maybe(value);
}
map(fn) {
// 你的代码:
// 如果value不为null/undefined,应用函数
}
flatMap(fn) {
// 你的代码:
// 扁平化map操作
}
getOrElse(defaultValue) {
// 你的代码:
// 获取值或返回默认值
}
}
// 使用Maybe处理可能为空的值
const result = Maybe.of('hello')
.map(s => s.toUpperCase())
.map(s => s + ' WORLD')
.getOrElse('默认值');
console.log(result);
🌐 模块化和工具
练习 5.1: ES6模块
javascript
// 练习:模块的导入导出
// 文件:mathUtils.js
// 你的代码:
// 1. 导出常量 PI
// 2. 导出函数 add, subtract, multiply, divide
// 3. 默认导出 Calculator 类
// 文件:stringUtils.js
// 你的代码:
// 1. 导出函数 capitalize, reverse, truncate
// 2. 导出对象 StringValidator(包含多个验证方法)
// 文件:main.js
// 你的代码:
// 1. 导入并使用 mathUtils
// 2. 导入并使用 stringUtils
// 3. 动态导入模块
练习 5.2: 错误处理和调试
javascript
// 练习:高级错误处理技巧
// 1. 自定义错误类
class ValidationError extends Error {
constructor(message, field) {
// 你的代码:
}
}
class NetworkError extends Error {
constructor(message, statusCode) {
// 你的代码:
}
}
// 2. 错误边界(模拟React错误边界)
class ErrorBoundary {
constructor() {
this.hasError = false;
this.error = null;
}
static getDerivedStateFromError(error) {
// 你的代码:
}
componentDidCatch(error, errorInfo) {
// 你的代码:
// 记录错误信息
}
}
// 3. 全局错误处理
function setupGlobalErrorHandling() {
// 你的代码:
// 设置全局错误监听器
// 处理未捕获的Promise rejection
}
// 4. 性能监控
class PerformanceMonitor {
static measure(name, fn) {
// 你的代码:
// 测量函数执行时间
}
static async measureAsync(name, asyncFn) {
// 你的代码:
// 测量异步函数执行时间
}
}
// 测试错误处理
try {
throw new ValidationError('用户名不能为空', 'username');
} catch (error) {
if (error instanceof ValidationError) {
console.log(`验证错误: ${error.message}, 字段: ${error.field}`);
}
}
🎯 综合项目练习
练习 6.1: 任务管理器
javascript
// 练习:创建一个功能完整的任务管理器
class TaskManager {
constructor() {
this.tasks = new Map();
this.nextId = 1;
this.observers = [];
}
// 添加任务
addTask(title, description, priority = 'medium') {
// 你的代码:
}
// 更新任务
updateTask(id, updates) {
// 你的代码:
}
// 删除任务
deleteTask(id) {
// 你的代码:
}
// 标记完成
completeTask(id) {
// 你的代码:
}
// 搜索任务
searchTasks(query) {
// 你的代码:
}
// 过滤任务
filterTasks(criteria) {
// 你的代码:
}
// 排序任务
sortTasks(sortBy) {
// 你的代码:
}
// 导出数据
exportToJSON() {
// 你的代码:
}
// 导入数据
importFromJSON(jsonData) {
// 你的代码:
}
// 观察者模式
subscribe(observer) {
// 你的代码:
}
unsubscribe(observer) {
// 你的代码:
}
notify(event, data) {
// 你的代码:
}
}
// 任务类
class Task {
constructor(id, title, description, priority) {
// 你的代码:
}
// 验证任务数据
static validate(taskData) {
// 你的代码:
}
}
// 使用示例
const taskManager = new TaskManager();
// 添加观察者
taskManager.subscribe((event, data) => {
console.log(`事件: ${event}`, data);
});
// 添加任务
taskManager.addTask('学习JavaScript', '完成进阶练习', 'high');
taskManager.addTask('写文档', '更新API文档', 'medium');
// 测试功能
console.log(taskManager.searchTasks('JavaScript'));
console.log(taskManager.filterTasks({priority: 'high'}));
练习 6.2: 数据可视化库
javascript
// 练习:创建一个简单的数据可视化库
class Chart {
constructor(container, options = {}) {
// 你的代码:
// 初始化图表容器和配置
}
// 渲染图表
render(data) {
// 你的代码:
// 抽象方法,子类实现
}
// 更新数据
update(newData) {
// 你的代码:
}
// 添加动画
animate(duration = 1000) {
// 你的代码:
}
// 事件处理
on(event, handler) {
// 你的代码:
}
// 销毁图表
destroy() {
// 你的代码:
}
}
// 柱状图
class BarChart extends Chart {
render(data) {
// 你的代码:
// 使用SVG或Canvas绘制柱状图
}
}
// 折线图
class LineChart extends Chart {
render(data) {
// 你的代码:
// 绘制折线图
}
}
// 饼图
class PieChart extends Chart {
render(data) {
// 你的代码:
// 绘制饼图
}
}
// 图表工厂
class ChartFactory {
static createChart(type, container, options) {
// 你的代码:
// 根据类型创建相应的图表
}
}
// 使用示例
const data = [
{label: '一月', value: 100},
{label: '二月', value: 150},
{label: '三月', value: 200},
{label: '四月', value: 180}
];
const chart = ChartFactory.createChart('bar', '#chart-container', {
width: 800,
height: 400,
color: '#3498db'
});
chart.render(data);
chart.animate();
💡 学习建议
- 深入理解概念:不要只记住语法,要理解背后的原理
- 实践项目:将学到的知识应用到实际项目中
- 阅读源码:研究优秀开源项目的代码实现
- 性能优化:关注代码的性能和内存使用
- 测试驱动:学会编写单元测试和集成测试
- 持续学习:JavaScript生态系统发展迅速,保持学习
🔗 相关链接
进阶之路需要耐心和坚持,每一个挑战都是成长的机会! 🌟