Skip to content

进阶练习

欢迎来到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();

💡 学习建议

  1. 深入理解概念:不要只记住语法,要理解背后的原理
  2. 实践项目:将学到的知识应用到实际项目中
  3. 阅读源码:研究优秀开源项目的代码实现
  4. 性能优化:关注代码的性能和内存使用
  5. 测试驱动:学会编写单元测试和集成测试
  6. 持续学习:JavaScript生态系统发展迅速,保持学习

🔗 相关链接


进阶之路需要耐心和坚持,每一个挑战都是成长的机会! 🌟