侧边栏壁纸
  • 累计撰写 29 篇文章
  • 累计创建 10 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

js

十点差三分
2025-05-11 / 0 评论 / 0 点赞 / 0 阅读 / 0 字

对于 JavaScript 新手,以下项目既能巩固基础又能逐步提升技能,按难度从易到难分类推荐:


初级项目(基础语法 + DOM 操作)

  1. 待办清单 (Todo List)

  2. 目标:DOM 操作、事件监听、数组操作

  3. 功能:增删任务、标记完成、本地存储

  4. 扩展:分类标签、搜索功能、拖拽排序

  5. 简易计算器

  6. 目标:逻辑处理、表单输入、数学运算

  7. 功能:加减乘除、括号优先级、历史记录

  8. 扩展:科学计算、主题切换

  9. 数字时钟/倒计时器

  10. 目标:Date 对象、定时器(setInterval

  11. 功能:实时显示时间、自定义倒计时、动画效果


中级项目(API 交互 + 动态内容)

  1. 天气预报应用

  2. 目标:Fetch API、JSON 解析、错误处理

  3. 工具:OpenWeatherMap API

  4. 功能:根据位置查询天气、显示图表、单位切换

  5. 随机名言/图片生成器

  6. 目标:异步请求、动态渲染

  7. 工具:免费 API(如 Quotable、Unsplash)

  8. 功能:点击刷新、分享按钮、收藏功能

  9. 简易博客系统

  10. 目标:CRUD 操作、表单验证

  11. 技术:LocalStorage 或 Firebase(后端)

  12. 功能:发布/编辑文章、评论互动


进阶项目(游戏 & 动画)

  1. 记忆卡牌游戏

  2. 目标:状态管理、CSS 动画

  3. 功能:翻牌匹配、计时计分、难度分级

  4. 贪吃蛇小游戏

  5. 目标:Canvas 绘图、键盘事件

  6. 扩展:关卡加速、道具系统

  7. 打字速度测试器

  8. 目标:字符串处理、实时统计

  9. 功能:随机文本、计时、准确率计算


全栈方向(可选后端技术)

  1. 用户登录系统

    • 后端:Node.js + Express 或 Firebase
    • 功能:注册/登录、密码重置、JWT 鉴权
  2. 实时聊天室

    • 技术:Socket.IO
    • 功能:多房间聊天、表情包、消息历史

框架入门(选一个方向)

  • React/Vue 项目:重构 Todo List 或博客系统,学习组件化开发。
  • Three.js 小游戏:3D 场景渲染(如旋转立方体、迷宫)。
  • Electron 桌面应用:将网页项目打包为本地应用。

资源推荐

  • API 合集:Public APIs (GitHub)、JSONPlaceholder
  • 设计灵感:CodePen、Dribbble
  • 调试工具:Chrome DevTools、ESLint

关键建议

  1. 从纯 JavaScript 开始,避免过早依赖框架。
  2. 每个项目完成后尝试优化代码(比如模块化、添加动画)。
  3. 遇到问题善用 console.log 调试,并阅读 MDN 文档。

通过逐步实践这些项目,你会对 JavaScript 的语法、异步编程和工程化有更深刻的理解! 🚀

以下是一些适合 JavaScript 进阶学习不使用框架的项目推荐,涵盖底层原理、复杂逻辑设计、性能优化等多个方向,结合搜索结果中的关键知识点进行综合设计:


一、底层工具库开发

  1. 自定义模板引擎

  2. 目标:实现类似 Mustache 的模板渲染,支持变量插值、条件判断、循环等。

  3. 技术点

    • 使用正则表达式解析模板语法(如 {{ variable }})。
    • 利用字符串替换或 DOM 操作动态生成 HTML。
    • 支持嵌套数据(如 user.name)的解析,参考 reduce 方法逐层提取数据。
  4. 扩展:添加缓存机制、模板继承功能。

  5. 轻量级状态管理库

  6. 目标:模仿 Redux 核心功能,实现状态订阅、派发、中间件机制。

  7. 技术点

    • 使用闭包和发布-订阅模式管理状态变更。
    • 通过高阶函数实现中间件链式调用(如日志、异步处理)。
  8. 扩展:支持 Immutable.js 风格的数据不可变性。


二、复杂应用与游戏开发

  1. Canvas 游戏(如俄罗斯方块、贪吃蛇)

  2. 目标:掌握 Canvas 绘图、游戏循环、碰撞检测。

  3. 技术点

    • 使用 requestAnimationFrame 实现流畅动画。
    • 面向对象设计(如 GameBlock 类)。
    • 键盘事件监听与状态同步。
  4. 扩展:添加音效、关卡系统、本地得分存储。

  5. 富文本编辑器

  6. 目标:支持文本格式(加粗、斜体)、图片插入、撤销重做。

  7. 技术点

    • 利用 document.execCommand 实现基础格式操作。
    • 通过 MutationObserver 监听内容变化,实现撤销栈。
    • 自定义选区与光标控制。

三、工程化与性能优化

  1. 模块加载器(类似 RequireJS)

  2. 目标:实现依赖解析、异步加载、作用域隔离。

  3. 技术点

    • 动态创建 <script> 标签加载 JS 文件。
    • 使用 evalFunction 构造函数隔离模块作用域。
    • 依赖拓扑排序解决循环引用。
  4. 性能监控工具

  5. 目标:统计页面 FPS、内存占用、资源加载时间。

  6. 技术点

    • 通过 Performance API 获取关键指标。
    • 使用 Web Worker 异步计算避免阻塞主线程。
    • 可视化数据(如折线图)通过 Canvas 或 SVG 渲染。

四、网络与数据交互

  1. WebSocket 实时聊天室

  2. 目标:实现多房间聊天、消息广播、用户列表同步。

  3. 技术点

    • 使用原生 WebSocket API 建立双向通信。
    • 消息队列与重连机制设计。
    • 数据压缩(如 JSON 序列化优化)。
  4. REST API 客户端

  5. 目标:封装 Fetch API,支持拦截器、缓存、错误重试。

  6. 技术点

    • 链式调用设计(如 client.get().then())。
    • 利用 localStorageIndexedDB 缓存响应数据。

五、底层原理实践

  1. 虚拟 DOM 实现

  2. 目标:理解 Diff 算法与高效 DOM 更新。

  3. 技术点

    • 通过 JS 对象描述 DOM 结构(如 { type: 'div', props: {} })。
    • 递归对比新旧虚拟 DOM 树,生成最小化 DOM 操作。
  4. Promise/A+ 规范实现

    • 目标:手写符合规范的 Promise 库。
    • 技术点
    • 状态机管理(pending/fulfilled/rejected)。
    • 链式调用与微任务队列(使用 MutationObserver 模拟)。

关键学习资源与技巧

  • 底层原理:参考网页 7 中的原型链、闭包、事件循环等核心概念。
  • 代码优化:使用现代语法如 async/await、箭头函数提升可读性。
  • 调试技巧:结合 Chrome DevTools 分析内存泄漏与性能瓶颈。

项目选择建议

  • 优先挑战:从工具库(如模板引擎)入手,逐步过渡到复杂应用(如游戏)。
  • 代码规范:使用 ESLint 强制代码风格,尝试 TypeScript 增强类型安全。
  • 性能意识:在关键路径(如渲染、网络请求)中优化时间复杂度与空间复杂度。

这些项目不仅能提升 JavaScript 的深度理解,还能培养工程化思维,为后续学习框架原理打下坚实基础。

以下是一个基于 JavaScript 进阶项目框架的系统化学习教程,结合核心知识点与实战练习,帮助你从底层原理到复杂应用逐步提升能力。教程分为 核心知识模块项目实战模块,每个模块均标注对应的知识点来源及引用。


阶段一:核心知识储备

1. 原型与原型链

  • 核心概念
  • 构造函数:通过 new 创建实例对象,prototype 属性定义共享方法。
  • 原型链:实例通过 __proto__ 向上查找属性,直到 Object.prototype
  • 继承:通过修改原型链实现(如 Woman.prototype = new Person())。
  • 练习
  • 手写一个 Person 构造函数,并为其原型添加 sayHello 方法。
  • 实现子类 Student 继承 Person,并重写方法。

2. 闭包与作用域

  • 核心概念
  • 闭包:函数保留其词法环境,即使外部函数已执行完毕(如计数器函数)。
  • 作用域链:变量查找机制,从当前作用域逐级向上至全局作用域。
  • 垃圾回收:标记清除算法管理内存,避免闭包导致的内存泄漏。
  • 练习
  • 实现一个缓存函数,利用闭包存储计算结果。
  • 分析以下代码的输出,解释作用域链:
    function outer() {
      let x = 10;
      function inner() {
        console.log(x);
      }
      return inner;
    }
    const fn = outer();
    fn(); // 输出?
    

3. 异步编程与事件循环

  • 核心概念
  • Promise:解决回调地狱,链式调用 .then().catch()
  • async/await:语法糖简化异步操作,需搭配 try/catch 处理错误。
  • 事件循环:宏任务(如 setTimeout)与微任务(如 Promise)的执行顺序。
  • 练习
  • 手写 Promise.all,处理多个异步请求的并发执行。
  • 分析以下代码的输出顺序:
    console.log(1);
    setTimeout(() => console.log(2), 0);
    Promise.resolve().then(() => console.log(3));
    console.log(4);
    

4. 模块化与设计模式

  • 核心概念
  • 模块化:使用 IIFEES6 Modules 封装代码。
  • 设计模式
    • 发布-订阅模式:实现事件驱动(如自定义事件系统)。
    • 单例模式:确保类仅有一个实例(如全局状态管理)。
  • 练习
  • 实现一个简单的发布-订阅系统,支持事件注册与触发。
  • 用单例模式封装一个日志工具类。

阶段二:项目实战驱动

项目1:自定义模板引擎

  • 目标:实现类似 Mustache 的模板渲染。
  • 知识点应用
  • 正则表达式:解析 {{ variable }} 语法。
  • 原型链:通过 Function 构造函数动态生成渲染函数。
  • 闭包:缓存已编译的模板提升性能。
  • 代码示例
    function compileTemplate(template) {
    const regex = /\{\{([^}]+)\}\}/g;
    return function(data) {
      return template.replace(regex, (_, key) => data[key.trim()]);
    };
    }
    const render = compileTemplate("Hello, {{ name }}!");
    console.log(render({ name: "World" })); // 输出 "Hello, World!"
    

项目2:轻量级状态管理库

  • 目标:模仿 Redux 核心功能。
  • 知识点应用
  • 闭包:封装状态 state,防止外部直接修改。
  • 发布-订阅模式:通过 subscribe 监听状态变化。
  • 中间件机制:链式调用高阶函数处理异步 action
  • 代码示例
    function createStore(reducer) {
    let state = reducer(undefined, {});
    const listeners = [];
    return {
      getState: () => state,
      dispatch: (action) => {
        state = reducer(state, action);
        listeners.forEach(listener => listener());
      },
      subscribe: (listener) => listeners.push(listener),
    };
    }
    

项目3:Canvas 俄罗斯方块游戏

  • 目标:掌握游戏循环与碰撞检测。
  • 知识点应用
  • 面向对象:定义 Block 类管理方块状态。
  • 事件循环:使用 requestAnimationFrame 实现流畅动画。
  • 性能优化:减少 Canvas 重绘次数。
  • 关键代码
    class Block {
    constructor(x, y) {
      this.x = x;
      this.y = y;
    }
    draw(ctx) {
      ctx.fillRect(this.x * 30, this.y * 30, 28, 28);
    }
    }
    

项目4:WebSocket 实时聊天室

  • 目标:实现多房间消息广播。
  • 知识点应用
  • WebSocket API:建立双向通信。
  • 事件驱动:处理 onmessageonclose 事件。
  • 数据序列化:使用 JSON.stringify 压缩消息。
  • 代码片段
    const ws = new WebSocket('ws://localhost:8080');
    ws.onmessage = (event) => {
    const message = JSON.parse(event.data);
    appendMessage(message.text);
    };
    

阶段三:工程化与调试

1. 模块加载器实现

  • 核心:动态加载脚本、依赖解析、作用域隔离。
  • 关键技术
  • evalFunction 执行模块代码。
  • 依赖拓扑排序解决循环引用。

2. 性能监控工具

  • 实现步骤
  • 使用 Performance API 获取 FPS 和内存指标。
  • 通过 Web Worker 异步计算数据。
  • 利用 Canvas 绘制实时折线图。

学习资源推荐

  • 文档:MDN Web Docs(原型链、闭包)
  • 调试工具:Chrome DevTools 的 Memory 和 Performance 面板
  • 开源项目:参考 Lodash(工具库)、Redux(状态管理)源码。

总结

通过以上分阶段学习,你将从 底层原理(原型链、闭包)过渡到 复杂应用(游戏、实时通信),最终掌握 工程化能力(模块化、性能优化)。每个项目均需结合知识点反复实践,并利用调试工具分析代码执行过程。

详细讲解 Promise 的用法

Promise 是 JavaScript 中处理异步操作的核心工具,它通过链式调用和状态管理,让异步代码更清晰、更易维护。以下是 Promise 的完整用法解析:


一、Promise 的基本概念

  1. 三种状态

  2. Pending(进行中):初始状态,尚未完成或拒绝。

  3. Fulfilled(已成功):操作成功完成,触发 .then() 中的回调。

  4. Rejected(已失败):操作失败,触发 .catch().then() 的第二个参数。

    const promise = new Promise((resolve, reject) => {
     if (/* 成功条件 */) {
       resolve("成功结果");
     } else {
       reject("失败原因");
     }
    });
    
  5. 状态不可逆

  6. 一旦状态变为 Fulfilled 或 Rejected,就不会再改变。


二、创建 Promise

通过 new Promise() 构造函数创建,接受一个执行器函数(executor):

  • resolve(value):将状态改为 Fulfilled,传递结果 value
  • reject(reason):将状态改为 Rejected,传递错误原因 reason

示例

const fetchData = new Promise((resolve, reject) => {
  setTimeout(() => {
    const data = { id: 1, name: "Alice" };
    // 模拟成功
    resolve(data);
    // 模拟失败:reject("Network Error");
  }, 1000);
});

三、链式调用:.then().catch()

  1. .then()

  2. 接受两个参数(均为可选):

    • onFulfilled:成功时的回调。
    • onRejected:失败时的回调。
  3. 返回一个新的 Promise,支持链式调用。

    fetchData
     .then((data) => {
       console.log("成功:", data);
       return data.id; // 传递给下一个 .then()
     })
     .then((id) => {
       console.log("ID:", id);
     });
    
  4. .catch()

  5. 捕获链中任意位置的错误。

  6. 相当于 .then(null, onRejected)

    fetchData
     .then((data) => {
       throw new Error("处理数据出错");
     })
     .catch((error) => {
       console.error("错误:", error); // 捕获所有错误
     });
    
  7. .finally()

  8. 无论成功或失败,最终都会执行。

  9. 常用于清理操作(如关闭加载动画)。

    fetchData
     .then((data) => console.log(data))
     .catch((error) => console.error(error))
     .finally(() => console.log("请求结束"));
    

四、处理多个 Promise

  1. Promise.all()

  2. 等待所有 Promise 完成,返回结果数组。

  3. 如果有一个失败,立即拒绝。

    const p1 = Promise.resolve(1);
    const p2 = Promise.resolve(2);
    Promise.all([p1, p2])
     .then(([result1, result2]) => {
       console.log(result1 + result2); // 3
     });
    
  4. Promise.race()

  5. 返回第一个完成(无论成功或失败)的 Promise 结果。

    const timeout = new Promise((_, reject) => {
     setTimeout(() => reject("超时"), 500);
    });
    const fetch = new Promise(resolve => {
     setTimeout(() => resolve("数据"), 1000);
    });
    Promise.race([fetch, timeout])
     .catch((error) => console.error(error)); // 输出 "超时"
    
  6. Promise.allSettled()

  7. 等待所有 Promise 完成,返回每个的结果和状态。

    Promise.allSettled([p1, p2])
     .then((results) => {
       results.forEach((result) => {
         if (result.status === "fulfilled") {
           console.log("成功:", result.value);
         } else {
           console.log("失败:", result.reason);
         }
       });
     });
    

五、错误处理最佳实践

  1. 避免“吞没错误”

  2. 每个 .then() 链末尾必须有一个 .catch()

    fetchData
     .then(processData)
     .catch((error) => console.error("全局捕获:", error));
    
  3. 手动抛出错误

  4. 使用 throwPromise.reject() 主动触发错误。

    .then((data) => {
     if (!data) throw new Error("数据不存在");
     // 或 return Promise.reject("错误");
    });
    

六、实际应用场景

  1. AJAX 请求

    function getJSON(url) {
     return new Promise((resolve, reject) => {
       const xhr = new XMLHttpRequest();
       xhr.open("GET", url);
       xhr.onload = () => {
         if (xhr.status === 200) {
           resolve(JSON.parse(xhr.response));
         } else {
           reject(xhr.statusText);
         }
       };
       xhr.onerror = () => reject("网络错误");
       xhr.send();
     });
    }
    
    getJSON("https://api.example.com/data")
     .then((data) => console.log(data));
    
  2. 顺序执行异步任务

    function task1() { return Promise.resolve(1); }
    function task2(n) { return Promise.resolve(n + 2); }
    
    task1()
     .then(task2)
     .then((result) => console.log(result)); // 3
    

七、常见问题与注意事项

  1. Promise 不会阻塞主线程

  2. 异步操作仍然在事件循环中执行,不会阻塞页面渲染。

  3. 微任务队列

  4. Promise 的回调属于微任务,优先于宏任务(如 setTimeout)执行。

    setTimeout(() => console.log("宏任务"), 0);
    Promise.resolve().then(() => console.log("微任务"));
    // 输出顺序:微任务 → 宏任务
    
  5. 避免冗余嵌套

  6. 使用链式调用替代回调地狱。

    // 错误示例
    fetchData.then((data) => {
     processData(data).then((result) => {
       saveResult(result).then(() => { /* ... */ });
     });
    });
    
    // 正确示例
    fetchData
     .then(processData)
     .then(saveResult)
     .then(() => { /* ... */ });
    

八、总结

  • 核心优势:通过链式调用和状态管理,让异步代码更清晰。
  • 关键方法.then(), .catch(), .finally(), Promise.all(), Promise.race()
  • 最佳实践:始终处理错误、避免嵌套、合理使用微任务特性。

通过结合理论学习和实际代码练习,可以深入掌握 Promise 的用法,为后续学习 async/await 打下坚实基础。

0

评论区