ゴゴゴゴゴ
Skip to content
JOJO
首页文章项目知识库相册音乐
全站搜索
  • Navigate
  • Go to Page
  • escClose
© 2026 JOJOBuilt with Next.js

四种声音一个时代

这里收藏周杰伦、王力宏、陶喆与林俊杰的专辑,也把四位创作者放回完整唱片的语境。陶喆以松弛的律动重塑华语 R&B,周杰伦把说唱、古典与中国式旋律带进流行音乐,王力宏在抒情、摇滚和东方元素之间拓宽制作边界,林俊杰则用细密旋律与宽阔声线记录城市情绪。这里不打乱曲序,也不把专辑压缩成热门单曲;挑一张封面,从第一首听到最后一首,感受开场、中段与尾声如何共同完成一段叙事。

左右滑动浏览,轻触封面,从第一首开始听

正在播放的唱片

选择一首歌曲查看歌词
专辑封面

专辑

    请选择一张唱片等待选曲
    0:00
    0:00

    键盘快捷键

    搜索
    / 或 ⌘K
    回到首页
    G H
    博客列表
    G B
    切换主题
    T
    关闭弹窗
    Esc
    显示帮助
    ?

    按 Esc 关闭此窗口

    Blog550
    • 全部文章(550)
    • 包管理工具(8)
      • Bun 完全指南
      • fnm 完全指南
      • ni 完全指南
      • npm 完全指南
      • nrm 完全指南
      • nvm 完全指南
      • pnpm 完全指南
      • Yarn 完全指南
    • 并发异步(7)
      • 异步任务取消机制
      • Promise静态方法汇总
      • 封装超时工具方法
      • 并发与并行
      • 封装并发任务方法
      • 一道并发相关的面试题
      • 文件写入的原子化与并发操作
    • 打包工具(10)
      • Bun - 全栈 JavaScript 运行时与打包器
      • esbuild - 用 Go 写的极速打包器
      • Parcel - 零配置的极速打包工具
      • Rolldown - Vite 团队打造的 Rust 打包器
      • Rollup - 专注于库开发的打包工具
      • Rspack - Rust 驱动的 Webpack 替代品
      • SWC - Rust 驱动的超快编译器
      • Turbopack - Rust 驱动的下一代打包工具
      • Vite - 下一代前端构建工具
      • Webpack - 功能最强大的模块打包器
    • 算法(74)
      • 课程必看
      • 算法基本概念
      • 评判算法的好坏
      • 复习对数
      • 常见的复杂度
      • 常见算法思维
      • 递归
      • 数据结构
      • 数组结构
      • 顺序查找
      • 二分查找
      • 插值查找
      • 冒泡排序
      • 选择排序
      • 插入排序
      • 折半插入排序
      • 希尔排序
      • 归并排序
      • 快速排序
      • 链表结构
      • 双向链表
      • 单向循环链表
      • 双向循环链表
      • 栈结构
      • 队列结构
      • 循环队列
      • 击鼓传花游戏
      • 双端队列
      • 回文检查器
      • 集合结构
      • 字典结构
      • 树结构
      • 二叉树
      • 二叉树遍历
      • 前序中序还原二叉树
      • 后序中序还原二叉树
      • 二叉树深度优先搜索
      • 二叉树广度优先搜索
      • 二叉树的比较
      • 二叉树diff算法
      • 二叉搜索树
      • 二叉搜索树常见操作
      • 平衡二叉树
      • 二叉树左单旋
      • 二叉树右单旋
      • 二叉树双旋
      • 二叉堆
      • 堆排序
      • 哈夫曼树
      • 图结构
      • 邻接矩阵
      • 邻接表
      • 构建图
      • 图的深度优先搜索
      • 图的广度优先搜索
      • 普里姆算法
      • 克鲁斯卡尔算法
      • LRU算法
      • 动态规划
      • 青蛙跳台阶
      • 不同路径问题
      • 凑零钱问题
      • 打家劫舍
      • 背包问题
      • 回溯算法
      • 数字组合
      • 电话号码字母组合
      • 复原IP地址
      • 数组子集
      • 贪心算法
      • 柠檬水找零
      • 摆动序列
      • 分发糖果
      • 跳跃游戏
    • 文档协同(12)
      • 课程说明
      • 文档协同常见方案
      • OT冲突算法
      • CRDT冲突算法
      • CRDT数据结构
      • 文章翻译
      • Yjs基础介绍
      • Yjs快速上手
      • Yjs细节补充
      • 监听机制
      • 标签页同步
      • WebSocket基础知识
    • 项目实战(1)
      • ShipAny:1小时开发海外游客「中国攻略 + AI旅游助手」SaaS网站
    • AI工具(9)
      • Claude Code 完全指南
      • ComfyUI 完全指南
      • GitHub Copilot 入门指南
      • Coze 完全指南
      • Cursor vs GitHub Copilot 全面对比
      • Cursor-完整指南
      • Dify 完全指南
      • Droid 完全指南
      • n8n 完全指南
    • Astro(5)
      • Astro 入门指南
      • Astro 路由与页面
      • Astro 组件与样式
      • Astro 内容集合
      • Astro 集成与部署
    • CSS(25)
      • CSS 选择器基础
      • CSS 盒模型
      • CSS 定位与层叠
      • 浮动与 BFC
      • Flexbox 布局
      • Grid 布局
      • 响应式设计
      • 伪类与伪元素
      • 现代选择器
      • CSS 变量
      • 层叠层
      • 过渡效果
      • CSS 动画
      • 变换与滤镜
      • 容器查询
      • 文字与排版
      • 背景与渐变
      • 滚动与溢出
      • 裁剪与遮罩
      • 颜色系统
      • 边框与阴影
      • 逻辑属性
      • CSS 函数
      • 多列布局
      • 用户交互
    • ES6+(40)
      • let 和 const 命令
      • 解构赋值基础
      • 解构赋值进阶
      • 字符串的扩展
      • 字符串新增方法
      • 正则表达式扩展
      • 数值的扩展
      • BigInt 大整数
      • 函数默认参数
      • rest 参数与扩展运算符
      • 箭头函数详解
      • 尾调用优化
      • 数组扩展方法
      • 数组新增方法
      • 数组不可变方法
      • 对象的扩展
      • Object 新增方法
      • Symbol 基础
      • Symbol 进阶应用
      • Set 数据结构
      • Map 数据结构
      • TypedArray 类型化数组
      • Proxy 基础
      • Proxy 进阶应用
      • Reflect 元编程
      • 元编程实战案例
      • 装饰器 Decorator
      • Iterator 迭代器
      • Generator 基础
      • Generator 进阶
      • Promise 基础
      • Promise 进阶
      • async 函数
      • await 与错误处理
      • 异步迭代
      • Class 基础
      • Class 继承
      • Module 语法
      • Module 加载
      • ES 新特性汇总
    • HTML(8)
      • HTML 入门:构建 Web 的基石
      • HTML5 语义化:让页面更有意义
      • HTML 表单基础:用户交互的起点
      • HTML 表单进阶:验证与现代特性
      • HTML 多媒体:音视频与响应式图片
      • HTML APIs(上):客户端存储完全指南
      • HTML APIs(下):交互与设备能力
      • Canvas 与 SVG:Web 图形绘制入门
    • JavaScript(30)
      • JavaScript 简介
      • 变量与数据类型
      • 运算符
      • 类型转换
      • 控制流语句
      • 函数基础
      • 对象基础
      • 数组基础
      • 原型与原型链
      • this 关键字
      • 面向对象编程
      • 作用域
      • 闭包
      • 执行上下文
      • DOM 选择器
      • DOM 操作
      • 事件处理
      • 事件委托
      • 错误处理
      • 调试技巧
      • 正则表达式
      • Date 日期对象
      • Math 对象
      • 定时器
      • JSON 处理
      • BOM 基础
      • 本地存储
      • 表单处理
      • AJAX 与 Fetch
      • 严格模式
    • Langchain(37)
      • Langchain基本介绍
      • 模型接口
      • 缓存
      • 提示词模板
      • 结构化提示词
      • Message消息对象
      • 消息占位
      • LCEL
      • 并发流式返回结果
      • Runnable接口
      • 条件路由
      • 字符串解析器
      • 结构化输出解析器
      • 列表输出解析器
      • JSON解析器
      • 正则解析器
      • 本地资源Loader
      • Web资源Loader
      • 文本切割
      • 嵌入处理
      • 内存型向量库
      • 检索优化
      • RAG实践
      • Memory基础
      • 自动维护聊天记录
      • 实现长程记忆
      • 持久化记忆
      • 第三方存储
      • Tools基础
      • Tools配置
      • Zod基础
      • LangChain中使用工具
      • 重新认识Agent
      • LangChain中创建Agent
      • Agent实践
      • 回退机制
      • 回调机制
    • LLM(34)
      • LLM发展历史
      • N-Gram模型
      • 词袋模型
      • 词元
      • 嵌入
      • Transformer内部结构
      • Transformer解码策略
      • Transformer块
      • 本地部署大模型
      • Agent
      • 流式返回信息
      • 支持上下文
      • 获取实时消息
      • 外接DeepSeek
      • Function Calling
      • MCP理论知识
      • Resources
      • Schema
      • 注册资源模板
      • Prompts
      • 监听资源更新
      • 远程通信方式
      • MCP Client
      • 大模型幻觉
      • RCT构词法
      • 提示词常见技巧
      • 基于反馈迭代优化
      • 改善提示效果
      • 提示词评估工具
      • RAG基础知识
      • RAG实践
      • RAG架构演进
      • 大模型微调
      • LoRA微调
    • MCP(8)
      • MCP 入门:连接 AI 与外部世界的桥梁
      • 搭建第一个 MCP Server
      • MCP Tools 深入:让 AI 具备行动能力
      • MCP Resources:向 AI 暴露数据
      • MCP Prompts:预定义 AI 交互模板
      • MCP Transport 与部署
      • 构建 MCP Client:集成到你的应用
      • 实战:构建文档助手 MCP Server
    • Nest(31)
      • 快速上手Nest Cli
      • 三层架构与MVC
      • IoC
      • Nest中的装饰器
      • 模块的基本概念
      • 什么是AOP
      • 中间件与守卫
      • 拦截器
      • 文件上传
      • 自定义装饰器
      • mysql相关回顾
      • 对于ORM的理解
      • 快速上手Redis
      • Nest中使用Redis
      • 状态保存方式
      • Nest中实现Session与JWT
      • JWT登录注册后端处理
      • 使用Passport与循环引用问题
      • 通过环境变量获取配置信息
      • RBAC权限设计1
      • RBAC权限设计2
      • Nest中使用Websocket
      • 日志处理
      • 面向切面的日志处理
      • 快速入门GraphQL
      • Nest中使用GraphQL
      • Swagger API文档
      • 单元测试与E2E测试
      • 安全防护实践
      • 定时任务与任务调度
      • Bull队列与异步任务
    • Next(36)
      • Next.js 简介
      • 项目创建与配置
      • App Router 概述
      • 创建第一个页面
      • 开发工具与调试
      • TypeScript 配置
      • 文件系统路由
      • 动态路由
      • 嵌套路由与布局
      • 路由组
      • 并行路由
      • 拦截路由
      • 导航与链接
      • 中间件
      • Server Components
      • Client Components
      • 混合渲染模式
      • Streaming 与 Suspense
      • 静态与动态渲染
      • 数据获取基础
      • 缓存策略
      • Server Actions
      • Route Handlers
      • 数据库集成
      • 错误处理
      • 图片优化
      • 字体优化
      • 脚本优化
      • 元数据与 SEO
      • 性能分析
      • 认证基础
      • NextAuth 集成
      • 环境变量与配置
      • 测试策略
      • 部署方案
      • 项目实战
    • Nuxt(36)
      • web应用变迁史
      • 课程说明
      • SSR初体验
      • 水合操作
      • 改造CSR项目
      • 基本介绍
      • 配置概览
      • 组件类型
      • Nuxt模块
      • 嵌套路由
      • 动态路由
      • 请求数据
      • server目录
      • 应用部署
      • 中间件
      • 插件
      • layers
      • 过渡
      • 状态管理
      • 全匹配路由
      • 路由补充知识
      • 自定义路由
      • 自定义模块
      • 自定义指令
      • meta相关处理
      • 渲染模式
      • 错误处理
      • 不同阶段错误
      • 客户端渲染组件
      • 其余内置组件
      • 配置相关细节
      • 常用组合式函数
      • 服务器引擎
      • NuxtUI
      • SSR注意事项
      • 课程收官
    • React(55)
      • 序章:React课程介绍
      • React 基本介绍
      • JSX 基础语法
      • 组件与事件绑定
      • 组件状态与数据传递
      • 表单
      • 生命周期
      • Hooks
      • React-router介绍
      • React-router v版本学生管理系统课堂笔记
      • React-redux 介绍
      • Antd介绍
      • coder station前台系统笔记
      • coder station 后台系统笔记
      • Antd Pro介绍
      • Dva介绍
      • Umi.js 介绍
      • 属性默认值和类型验证
      • 高阶组件
      • Ref
      • Context
      • Render Props
      • Portals
      • 错误边界
      • 组件渲染性能优化
      • 前端框架的理解
      • Scheduler调度延时任务
      • 最小堆
      • React中的位运算
      • beginWork工作流程
      • completeWork工作流程
      • 图解diff算法
      • commit 工作流程
      • lane模型
      • React 中的事件
      • Hooks原理
      • React和Vue描述页面的区别
      • useState和useReducer
      • effect相关hook
      • useCallback和useMemo
      • useRef
      • Update
      • 性能优化策略之eagerState
      • 性能优化策略之bailout
      • bailout和ContextAPI
      • 性能优化对日常开发启示
      • 前端框架的分类
      • 虚拟 DOM
      • React 整体架构
      • React 渲染流程
      • Fiber双缓冲
      • MessageChannel
      • Scheduler调度普通任务
      • 课程介绍
      • 课程总结
    • ReactNative(33)
      • RN 基本介绍
      • 快速搭建 RN 开发环境
      • 复习 React 基础知识
      • RN 基础知识
      • 实战案例
      • RN 内置基础组件
      • 容器组件
      • Pressable 组件
      • 列表组件
      • 功能组件
      • 第三方组件库
      • 自定义组件案例:弹框组件
      • 自定义组件案例:单选组件
      • 基础API
      • 屏幕API
      • 设备API
      • 动画API
      • 手势API
      • React Navigation简介
      • 参数传递和标题栏信息配置
      • 嵌套路由与生命周期
      • 其他类型的导航
      • 状态管理介绍
      • Redux
      • 其他第三方库
      • Expo SDK
      • Fabric 架构
      • 渲染、提交和挂载
      • 实现跨平台
      • 扁平化视图
      • 线程模型
      • 如何打包发布应用
      • 通过 React Native CLI 搭建环境
    • TailwindCSS(7)
      • TailwindCSS基础介绍
      • 环境搭建与配置
      • 布局系统
      • 间距与尺寸系统
      • 颜色与主题
      • 响应式设计
      • 交互与动画
    • TypeScript(35)
      • 初识 TypeScript
      • 基础类型
      • 数组与元组
      • 对象类型
      • 函数类型
      • 类型推断与断言
      • 联合类型与交叉类型
      • 字面量类型与类型别名
      • 接口基础
      • 接口进阶
      • 接口继承与实现
      • 类基础
      • 类的访问修饰符
      • 类的继承
      • 类与接口对比
      • 泛型基础
      • 泛型接口与泛型类
      • 泛型约束
      • 内置工具类型(上)
      • 内置工具类型(下)
      • 泛型实战
      • 类型守卫
      • 类型收窄
      • 索引类型与索引签名
      • 映射类型
      • 条件类型
      • infer 关键字
      • 模板字面量类型
      • 模块系统
      • 命名空间
      • 声明文件基础
      • 声明文件进阶
      • tsconfig 配置详解
      • 类型体操入门
      • TypeScript 最佳实践
    • 杂谈(9)
      • Cloudflare 全栈部署指南
      • Creem 支付集成指南
      • Dokploy 自托管部署指南
      • GitHub OAuth 登录集成指南
      • Google OAuth 登录集成指南
      • Stripe 支付集成指南
      • Supabase 完全指南
      • Vercel 自动化部署指南
      • Zeabur 部署指南
    • 全部文章(550)
    • 包管理工具(8)
      • Bun 完全指南
      • fnm 完全指南
      • ni 完全指南
      • npm 完全指南
      • nrm 完全指南
      • nvm 完全指南
      • pnpm 完全指南
      • Yarn 完全指南
    • 并发异步(7)
      • 异步任务取消机制
      • Promise静态方法汇总
      • 封装超时工具方法
      • 并发与并行
      • 封装并发任务方法
      • 一道并发相关的面试题
      • 文件写入的原子化与并发操作
    • 打包工具(10)
      • Bun - 全栈 JavaScript 运行时与打包器
      • esbuild - 用 Go 写的极速打包器
      • Parcel - 零配置的极速打包工具
      • Rolldown - Vite 团队打造的 Rust 打包器
      • Rollup - 专注于库开发的打包工具
      • Rspack - Rust 驱动的 Webpack 替代品
      • SWC - Rust 驱动的超快编译器
      • Turbopack - Rust 驱动的下一代打包工具
      • Vite - 下一代前端构建工具
      • Webpack - 功能最强大的模块打包器
    • 算法(74)
      • 课程必看
      • 算法基本概念
      • 评判算法的好坏
      • 复习对数
      • 常见的复杂度
      • 常见算法思维
      • 递归
      • 数据结构
      • 数组结构
      • 顺序查找
      • 二分查找
      • 插值查找
      • 冒泡排序
      • 选择排序
      • 插入排序
      • 折半插入排序
      • 希尔排序
      • 归并排序
      • 快速排序
      • 链表结构
      • 双向链表
      • 单向循环链表
      • 双向循环链表
      • 栈结构
      • 队列结构
      • 循环队列
      • 击鼓传花游戏
      • 双端队列
      • 回文检查器
      • 集合结构
      • 字典结构
      • 树结构
      • 二叉树
      • 二叉树遍历
      • 前序中序还原二叉树
      • 后序中序还原二叉树
      • 二叉树深度优先搜索
      • 二叉树广度优先搜索
      • 二叉树的比较
      • 二叉树diff算法
      • 二叉搜索树
      • 二叉搜索树常见操作
      • 平衡二叉树
      • 二叉树左单旋
      • 二叉树右单旋
      • 二叉树双旋
      • 二叉堆
      • 堆排序
      • 哈夫曼树
      • 图结构
      • 邻接矩阵
      • 邻接表
      • 构建图
      • 图的深度优先搜索
      • 图的广度优先搜索
      • 普里姆算法
      • 克鲁斯卡尔算法
      • LRU算法
      • 动态规划
      • 青蛙跳台阶
      • 不同路径问题
      • 凑零钱问题
      • 打家劫舍
      • 背包问题
      • 回溯算法
      • 数字组合
      • 电话号码字母组合
      • 复原IP地址
      • 数组子集
      • 贪心算法
      • 柠檬水找零
      • 摆动序列
      • 分发糖果
      • 跳跃游戏
    • 文档协同(12)
      • 课程说明
      • 文档协同常见方案
      • OT冲突算法
      • CRDT冲突算法
      • CRDT数据结构
      • 文章翻译
      • Yjs基础介绍
      • Yjs快速上手
      • Yjs细节补充
      • 监听机制
      • 标签页同步
      • WebSocket基础知识
    • 项目实战(1)
      • ShipAny:1小时开发海外游客「中国攻略 + AI旅游助手」SaaS网站
    • AI工具(9)
      • Claude Code 完全指南
      • ComfyUI 完全指南
      • GitHub Copilot 入门指南
      • Coze 完全指南
      • Cursor vs GitHub Copilot 全面对比
      • Cursor-完整指南
      • Dify 完全指南
      • Droid 完全指南
      • n8n 完全指南
    • Astro(5)
      • Astro 入门指南
      • Astro 路由与页面
      • Astro 组件与样式
      • Astro 内容集合
      • Astro 集成与部署
    • CSS(25)
      • CSS 选择器基础
      • CSS 盒模型
      • CSS 定位与层叠
      • 浮动与 BFC
      • Flexbox 布局
      • Grid 布局
      • 响应式设计
      • 伪类与伪元素
      • 现代选择器
      • CSS 变量
      • 层叠层
      • 过渡效果
      • CSS 动画
      • 变换与滤镜
      • 容器查询
      • 文字与排版
      • 背景与渐变
      • 滚动与溢出
      • 裁剪与遮罩
      • 颜色系统
      • 边框与阴影
      • 逻辑属性
      • CSS 函数
      • 多列布局
      • 用户交互
    • ES6+(40)
      • let 和 const 命令
      • 解构赋值基础
      • 解构赋值进阶
      • 字符串的扩展
      • 字符串新增方法
      • 正则表达式扩展
      • 数值的扩展
      • BigInt 大整数
      • 函数默认参数
      • rest 参数与扩展运算符
      • 箭头函数详解
      • 尾调用优化
      • 数组扩展方法
      • 数组新增方法
      • 数组不可变方法
      • 对象的扩展
      • Object 新增方法
      • Symbol 基础
      • Symbol 进阶应用
      • Set 数据结构
      • Map 数据结构
      • TypedArray 类型化数组
      • Proxy 基础
      • Proxy 进阶应用
      • Reflect 元编程
      • 元编程实战案例
      • 装饰器 Decorator
      • Iterator 迭代器
      • Generator 基础
      • Generator 进阶
      • Promise 基础
      • Promise 进阶
      • async 函数
      • await 与错误处理
      • 异步迭代
      • Class 基础
      • Class 继承
      • Module 语法
      • Module 加载
      • ES 新特性汇总
    • HTML(8)
      • HTML 入门:构建 Web 的基石
      • HTML5 语义化:让页面更有意义
      • HTML 表单基础:用户交互的起点
      • HTML 表单进阶:验证与现代特性
      • HTML 多媒体:音视频与响应式图片
      • HTML APIs(上):客户端存储完全指南
      • HTML APIs(下):交互与设备能力
      • Canvas 与 SVG:Web 图形绘制入门
    • JavaScript(30)
      • JavaScript 简介
      • 变量与数据类型
      • 运算符
      • 类型转换
      • 控制流语句
      • 函数基础
      • 对象基础
      • 数组基础
      • 原型与原型链
      • this 关键字
      • 面向对象编程
      • 作用域
      • 闭包
      • 执行上下文
      • DOM 选择器
      • DOM 操作
      • 事件处理
      • 事件委托
      • 错误处理
      • 调试技巧
      • 正则表达式
      • Date 日期对象
      • Math 对象
      • 定时器
      • JSON 处理
      • BOM 基础
      • 本地存储
      • 表单处理
      • AJAX 与 Fetch
      • 严格模式
    • Langchain(37)
      • Langchain基本介绍
      • 模型接口
      • 缓存
      • 提示词模板
      • 结构化提示词
      • Message消息对象
      • 消息占位
      • LCEL
      • 并发流式返回结果
      • Runnable接口
      • 条件路由
      • 字符串解析器
      • 结构化输出解析器
      • 列表输出解析器
      • JSON解析器
      • 正则解析器
      • 本地资源Loader
      • Web资源Loader
      • 文本切割
      • 嵌入处理
      • 内存型向量库
      • 检索优化
      • RAG实践
      • Memory基础
      • 自动维护聊天记录
      • 实现长程记忆
      • 持久化记忆
      • 第三方存储
      • Tools基础
      • Tools配置
      • Zod基础
      • LangChain中使用工具
      • 重新认识Agent
      • LangChain中创建Agent
      • Agent实践
      • 回退机制
      • 回调机制
    • LLM(34)
      • LLM发展历史
      • N-Gram模型
      • 词袋模型
      • 词元
      • 嵌入
      • Transformer内部结构
      • Transformer解码策略
      • Transformer块
      • 本地部署大模型
      • Agent
      • 流式返回信息
      • 支持上下文
      • 获取实时消息
      • 外接DeepSeek
      • Function Calling
      • MCP理论知识
      • Resources
      • Schema
      • 注册资源模板
      • Prompts
      • 监听资源更新
      • 远程通信方式
      • MCP Client
      • 大模型幻觉
      • RCT构词法
      • 提示词常见技巧
      • 基于反馈迭代优化
      • 改善提示效果
      • 提示词评估工具
      • RAG基础知识
      • RAG实践
      • RAG架构演进
      • 大模型微调
      • LoRA微调
    • MCP(8)
      • MCP 入门:连接 AI 与外部世界的桥梁
      • 搭建第一个 MCP Server
      • MCP Tools 深入:让 AI 具备行动能力
      • MCP Resources:向 AI 暴露数据
      • MCP Prompts:预定义 AI 交互模板
      • MCP Transport 与部署
      • 构建 MCP Client:集成到你的应用
      • 实战:构建文档助手 MCP Server
    • Nest(31)
      • 快速上手Nest Cli
      • 三层架构与MVC
      • IoC
      • Nest中的装饰器
      • 模块的基本概念
      • 什么是AOP
      • 中间件与守卫
      • 拦截器
      • 文件上传
      • 自定义装饰器
      • mysql相关回顾
      • 对于ORM的理解
      • 快速上手Redis
      • Nest中使用Redis
      • 状态保存方式
      • Nest中实现Session与JWT
      • JWT登录注册后端处理
      • 使用Passport与循环引用问题
      • 通过环境变量获取配置信息
      • RBAC权限设计1
      • RBAC权限设计2
      • Nest中使用Websocket
      • 日志处理
      • 面向切面的日志处理
      • 快速入门GraphQL
      • Nest中使用GraphQL
      • Swagger API文档
      • 单元测试与E2E测试
      • 安全防护实践
      • 定时任务与任务调度
      • Bull队列与异步任务
    • Next(36)
      • Next.js 简介
      • 项目创建与配置
      • App Router 概述
      • 创建第一个页面
      • 开发工具与调试
      • TypeScript 配置
      • 文件系统路由
      • 动态路由
      • 嵌套路由与布局
      • 路由组
      • 并行路由
      • 拦截路由
      • 导航与链接
      • 中间件
      • Server Components
      • Client Components
      • 混合渲染模式
      • Streaming 与 Suspense
      • 静态与动态渲染
      • 数据获取基础
      • 缓存策略
      • Server Actions
      • Route Handlers
      • 数据库集成
      • 错误处理
      • 图片优化
      • 字体优化
      • 脚本优化
      • 元数据与 SEO
      • 性能分析
      • 认证基础
      • NextAuth 集成
      • 环境变量与配置
      • 测试策略
      • 部署方案
      • 项目实战
    • Nuxt(36)
      • web应用变迁史
      • 课程说明
      • SSR初体验
      • 水合操作
      • 改造CSR项目
      • 基本介绍
      • 配置概览
      • 组件类型
      • Nuxt模块
      • 嵌套路由
      • 动态路由
      • 请求数据
      • server目录
      • 应用部署
      • 中间件
      • 插件
      • layers
      • 过渡
      • 状态管理
      • 全匹配路由
      • 路由补充知识
      • 自定义路由
      • 自定义模块
      • 自定义指令
      • meta相关处理
      • 渲染模式
      • 错误处理
      • 不同阶段错误
      • 客户端渲染组件
      • 其余内置组件
      • 配置相关细节
      • 常用组合式函数
      • 服务器引擎
      • NuxtUI
      • SSR注意事项
      • 课程收官
    • React(55)
      • 序章:React课程介绍
      • React 基本介绍
      • JSX 基础语法
      • 组件与事件绑定
      • 组件状态与数据传递
      • 表单
      • 生命周期
      • Hooks
      • React-router介绍
      • React-router v版本学生管理系统课堂笔记
      • React-redux 介绍
      • Antd介绍
      • coder station前台系统笔记
      • coder station 后台系统笔记
      • Antd Pro介绍
      • Dva介绍
      • Umi.js 介绍
      • 属性默认值和类型验证
      • 高阶组件
      • Ref
      • Context
      • Render Props
      • Portals
      • 错误边界
      • 组件渲染性能优化
      • 前端框架的理解
      • Scheduler调度延时任务
      • 最小堆
      • React中的位运算
      • beginWork工作流程
      • completeWork工作流程
      • 图解diff算法
      • commit 工作流程
      • lane模型
      • React 中的事件
      • Hooks原理
      • React和Vue描述页面的区别
      • useState和useReducer
      • effect相关hook
      • useCallback和useMemo
      • useRef
      • Update
      • 性能优化策略之eagerState
      • 性能优化策略之bailout
      • bailout和ContextAPI
      • 性能优化对日常开发启示
      • 前端框架的分类
      • 虚拟 DOM
      • React 整体架构
      • React 渲染流程
      • Fiber双缓冲
      • MessageChannel
      • Scheduler调度普通任务
      • 课程介绍
      • 课程总结
    • ReactNative(33)
      • RN 基本介绍
      • 快速搭建 RN 开发环境
      • 复习 React 基础知识
      • RN 基础知识
      • 实战案例
      • RN 内置基础组件
      • 容器组件
      • Pressable 组件
      • 列表组件
      • 功能组件
      • 第三方组件库
      • 自定义组件案例:弹框组件
      • 自定义组件案例:单选组件
      • 基础API
      • 屏幕API
      • 设备API
      • 动画API
      • 手势API
      • React Navigation简介
      • 参数传递和标题栏信息配置
      • 嵌套路由与生命周期
      • 其他类型的导航
      • 状态管理介绍
      • Redux
      • 其他第三方库
      • Expo SDK
      • Fabric 架构
      • 渲染、提交和挂载
      • 实现跨平台
      • 扁平化视图
      • 线程模型
      • 如何打包发布应用
      • 通过 React Native CLI 搭建环境
    • TailwindCSS(7)
      • TailwindCSS基础介绍
      • 环境搭建与配置
      • 布局系统
      • 间距与尺寸系统
      • 颜色与主题
      • 响应式设计
      • 交互与动画
    • TypeScript(35)
      • 初识 TypeScript
      • 基础类型
      • 数组与元组
      • 对象类型
      • 函数类型
      • 类型推断与断言
      • 联合类型与交叉类型
      • 字面量类型与类型别名
      • 接口基础
      • 接口进阶
      • 接口继承与实现
      • 类基础
      • 类的访问修饰符
      • 类的继承
      • 类与接口对比
      • 泛型基础
      • 泛型接口与泛型类
      • 泛型约束
      • 内置工具类型(上)
      • 内置工具类型(下)
      • 泛型实战
      • 类型守卫
      • 类型收窄
      • 索引类型与索引签名
      • 映射类型
      • 条件类型
      • infer 关键字
      • 模板字面量类型
      • 模块系统
      • 命名空间
      • 声明文件基础
      • 声明文件进阶
      • tsconfig 配置详解
      • 类型体操入门
      • TypeScript 最佳实践
    • 杂谈(9)
      • Cloudflare 全栈部署指南
      • Creem 支付集成指南
      • Dokploy 自托管部署指南
      • GitHub OAuth 登录集成指南
      • Google OAuth 登录集成指南
      • Stripe 支付集成指南
      • Supabase 完全指南
      • Vercel 自动化部署指南
      • Zeabur 部署指南

    函数基础

    2025年12月3日 · 12 min
    ChatGPTClaude

    函数是 JavaScript 的核心。它不仅是代码复用的基本单位,更是一等公民——可以像普通值一样传递和操作。

    🎯 定义函数

    函数声明

    // 函数声明(Function Declaration)
    function greet(name) {
    return `你好,${name}!`
    }
    console.log(greet('张三')) // "你好,张三!"
    // 函数声明会被提升(hoisting)
    sayHello() // "Hello!"(可以在声明前调用)
    function sayHello() {
    console.log('Hello!')
    }

    函数表达式

    // 函数表达式(Function Expression)
    const greet = function (name) {
    return `你好,${name}!`
    }
    // 不会被提升
    // sayHi() // ReferenceError
    const sayHi = function () {
    console.log('Hi!')
    }
    // 命名函数表达式(用于递归和调试)
    const factorial = function fact(n) {
    if (n <= 1) return 1
    return n * fact(n - 1) // 内部可以用 fact
    }
    // fact(5) // ReferenceError(外部不能用 fact)

    箭头函数

    // 箭头函数(ES6)
    const add = (a, b) => a + b
    // 单参数可省略括号
    const double = (n) => n * 2
    // 无参数需要括号
    const random = () => Math.random()
    // 多行需要花括号和 return
    const greet = (name) => {
    const greeting = `你好,${name}!`
    return greeting
    }
    // 返回对象字面量需要包在括号里
    const createUser = (name) => ({ name, createdAt: Date.now() })

    构造函数

    // 使用 Function 构造函数(不推荐)
    const add = new Function('a', 'b', 'return a + b')
    console.log(add(1, 2)) // 3
    // 🔶 有安全和性能问题,极少使用

    函数参数

    基本参数

    function add(a, b) {
    return a + b
    }
    add(1, 2) // 3
    add(1) // NaN(b 是 undefined)
    add(1, 2, 3) // 3(多余参数被忽略)

    默认参数

    // ES6 默认参数
    function greet(name = '游客', greeting = '你好') {
    return `${greeting},${name}!`
    }
    greet() // "你好,游客!"
    greet('张三') // "你好,张三!"
    greet('张三', '早上好') // "早上好,张三!"
    // 只传第二个参数
    greet(undefined, '晚上好') // "晚上好,游客!"
    // 默认值可以是表达式
    function getTimestamp(date = new Date()) {
    return date.getTime()
    }
    // 默认值可以引用前面的参数
    function createRect(width, height = width) {
    return { width, height }
    }
    createRect(10) // { width: 10, height: 10 }

    剩余参数

    // 收集剩余参数到数组
    function sum(...numbers) {
    return numbers.reduce((a, b) => a + b, 0)
    }
    sum(1, 2, 3) // 6
    sum(1, 2, 3, 4, 5) // 15
    // 与普通参数结合
    function log(level, ...messages) {
    console.log(`[${level}]`, ...messages)
    }
    log('INFO', '用户登录', '用户ID: 123')
    // [INFO] 用户登录 用户ID: 123
    // 🔶 剩余参数必须是最后一个
    // function bad(...rest, last) {} // SyntaxError

    arguments 对象

    // 传统方式(非箭头函数)
    function sum() {
    let total = 0
    for (let i = 0; i < arguments.length; i++) {
    total += arguments[i]
    }
    return total
    }
    sum(1, 2, 3) // 6
    // arguments 是类数组,不是真正的数组
    function showArgs() {
    console.log(arguments.length) // 3
    console.log(arguments[0]) // 'a'
    // arguments.map(...) // TypeError
    // 转为数组
    const args = Array.from(arguments)
    // 或
    const args2 = [...arguments]
    }
    showArgs('a', 'b', 'c')
    // 🔶 箭头函数没有 arguments
    const arrowFn = () => {
    // console.log(arguments) // ReferenceError
    }
    // 在箭头函数中使用剩余参数代替
    const arrowSum = (...args) => args.reduce((a, b) => a + b, 0)

    解构参数

    // 对象解构
    function createUser({ name, age, city = '未知' }) {
    return { name, age, city }
    }
    createUser({ name: '张三', age: 25 })
    // { name: "张三", age: 25, city: "未知" }
    // 数组解构
    function swap([a, b]) {
    return [b, a]
    }
    swap([1, 2]) // [2, 1]
    // 配合默认值
    function config({ host = 'localhost', port = 3000 } = {}) {
    return { host, port }
    }
    config() // { host: "localhost", port: 3000 }
    config({ port: 8080 }) // { host: "localhost", port: 8080 }

    返回值

    return 语句

    // 返回值
    function add(a, b) {
    return a + b // 返回结果并结束函数
    }
    // 提前返回
    function divide(a, b) {
    if (b === 0) {
    return null // 提前返回,下面的代码不执行
    }
    return a / b
    }
    // 没有 return 或 return 后没有值,返回 undefined
    function noReturn() {
    console.log('执行')
    }
    console.log(noReturn()) // undefined
    function emptyReturn() {
    return
    }
    console.log(emptyReturn()) // undefined

    返回多个值

    // 返回数组
    function minMax(arr) {
    return [Math.min(...arr), Math.max(...arr)]
    }
    const [min, max] = minMax([3, 1, 4, 1, 5])
    // 返回对象
    function getUser() {
    return {
    name: '张三',
    age: 25,
    city: '北京',
    }
    }
    const { name, age } = getUser()
    // 返回函数
    function createMultiplier(factor) {
    return function (number) {
    return number * factor
    }
    }
    const double = createMultiplier(2)
    double(5) // 10

    换行陷阱

    // 🔶 return 后换行会自动插入分号
    function bad() {
    return
    {
    value: 1
    }
    }
    bad() // undefined(不是对象!)
    // ✅ 正确写法
    function good() {
    return {
    value: 1,
    }
    }
    // 或者
    function good2() {
    return {
    value: 1,
    }
    }

    函数作用域

    词法作用域

    // 函数作用域由定义位置决定,不是调用位置
    const x = 10
    function outer() {
    const x = 20
    function inner() {
    console.log(x) // 查找最近的 x
    }
    return inner
    }
    const fn = outer()
    fn() // 20(不是 10)

    变量遮蔽

    const name = '全局'
    function showName() {
    const name = '局部' // 遮蔽全局变量
    console.log(name)
    }
    showName() // "局部"
    console.log(name) // "全局"

    闭包预览

    // 函数可以记住创建时的作用域
    function createCounter() {
    let count = 0 // 私有变量
    return function () {
    count++
    return count
    }
    }
    const counter = createCounter()
    console.log(counter()) // 1
    console.log(counter()) // 2
    console.log(counter()) // 3
    // count 对外部不可见,但函数可以访问

    函数是一等公民

    赋值给变量

    const greet = function (name) {
    return `你好,${name}`
    }
    // 可以重新赋值
    let fn = greet
    console.log(fn('张三')) // "你好,张三"

    作为参数传递

    // 回调函数
    function processArray(arr, callback) {
    const result = []
    for (const item of arr) {
    result.push(callback(item))
    }
    return result
    }
    const numbers = [1, 2, 3]
    const doubled = processArray(numbers, (n) => n * 2)
    console.log(doubled) // [2, 4, 6]
    // 数组方法
    numbers.map((n) => n * 2)
    numbers.filter((n) => n > 1)
    numbers.forEach((n) => console.log(n))

    作为返回值

    // 高阶函数
    function withLogging(fn) {
    return function (...args) {
    console.log('调用参数:', args)
    const result = fn(...args)
    console.log('返回结果:', result)
    return result
    }
    }
    const add = (a, b) => a + b
    const loggedAdd = withLogging(add)
    loggedAdd(1, 2)
    // 调用参数: [1, 2]
    // 返回结果: 3

    存储在数据结构中

    // 存储在数组中
    const operations = [(x) => x + 1, (x) => x * 2, (x) => x ** 2]
    let value = 2
    for (const op of operations) {
    value = op(value)
    }
    console.log(value) // ((2 + 1) * 2) ** 2 = 36
    // 存储在对象中
    const calculator = {
    add: (a, b) => a + b,
    subtract: (a, b) => a - b,
    multiply: (a, b) => a * b,
    divide: (a, b) => a / b,
    }
    calculator.add(5, 3) // 8

    立即执行函数(IIFE)

    // 定义后立即执行
    ;(function () {
    const private = '私有变量'
    console.log(private)
    })()
    // 箭头函数版本
    ;(() => {
    console.log('立即执行')
    })()
    // 传递参数
    ;(function (name) {
    console.log(`你好,${name}`)
    })('张三')
    // 返回值
    const result = (function () {
    return 42
    })()
    // 用于创建私有作用域(ES6 前的模块化)
    const counter = (function () {
    let count = 0
    return {
    increment() {
    count++
    },
    getCount() {
    return count
    },
    }
    })()

    递归函数

    // 阶乘
    function factorial(n) {
    if (n <= 1) return 1
    return n * factorial(n - 1)
    }
    factorial(5) // 120
    // 斐波那契数列
    function fibonacci(n) {
    if (n <= 1) return n
    return fibonacci(n - 1) + fibonacci(n - 2)
    }
    fibonacci(10) // 55
    // 🔶 简单递归效率低,可以用记忆化优化
    function memoizedFib() {
    const cache = {}
    return function fib(n) {
    if (n in cache) return cache[n]
    if (n <= 1) return n
    cache[n] = fib(n - 1) + fib(n - 2)
    return cache[n]
    }
    }
    const fib = memoizedFib()
    fib(50) // 快速计算
    // 深度遍历对象
    function deepClone(obj) {
    if (obj === null || typeof obj !== 'object') {
    return obj
    }
    const clone = Array.isArray(obj) ? [] : {}
    for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
    clone[key] = deepClone(obj[key])
    }
    }
    return clone
    }

    函数的属性和方法

    name 属性

    function foo() {}
    console.log(foo.name) // "foo"
    const bar = function () {}
    console.log(bar.name) // "bar"
    const baz = function qux() {}
    console.log(baz.name) // "qux"
    console.log((() => {}).name) // ""

    length 属性

    // 形参数量(不含默认值和剩余参数)
    function fn1(a) {}
    function fn2(a, b) {}
    function fn3(a, b = 1) {}
    function fn4(a, ...rest) {}
    console.log(fn1.length) // 1
    console.log(fn2.length) // 2
    console.log(fn3.length) // 1(默认参数不计入)
    console.log(fn4.length) // 1(剩余参数不计入)

    call 和 apply

    function greet(greeting, punctuation) {
    return `${greeting},${this.name}${punctuation}`
    }
    const person = { name: '张三' }
    // call:参数逐个传递
    greet.call(person, '你好', '!') // "你好,张三!"
    // apply:参数作为数组传递
    greet.apply(person, ['你好', '!']) // "你好,张三!"
    // 实际应用:借用数组方法
    const arrayLike = { 0: 'a', 1: 'b', length: 2 }
    Array.prototype.slice.call(arrayLike) // ["a", "b"]

    bind

    const person = { name: '张三' }
    function greet() {
    return `你好,${this.name}`
    }
    // 创建绑定 this 的新函数
    const boundGreet = greet.bind(person)
    boundGreet() // "你好,张三"
    // 预设参数(柯里化)
    function add(a, b, c) {
    return a + b + c
    }
    const add5 = add.bind(null, 5) // 预设 a = 5
    add5(3, 2) // 10
    const add5and3 = add.bind(null, 5, 3) // 预设 a = 5, b = 3
    add5and3(2) // 10

    最佳实践

    函数命名

    // 动词开头,描述行为
    function getUserById(id) {}
    function validateEmail(email) {}
    function calculateTotal(items) {}
    // 布尔返回值用 is/has/can
    function isValid(value) {}
    function hasPermission(user) {}
    function canEdit(document) {}
    // 事件处理用 handle/on
    function handleClick(event) {}
    function onSubmit(data) {}

    单一职责

    // 🔶 做太多事
    function processUser(user) {
    // 验证
    if (!user.name) throw new Error('名字必填')
    // 格式化
    user.name = user.name.trim()
    // 保存
    database.save(user)
    // 发送邮件
    email.send(user.email, '欢迎')
    }
    // ✅ 拆分职责
    function validateUser(user) {
    if (!user.name) throw new Error('名字必填')
    }
    function formatUser(user) {
    return { ...user, name: user.name.trim() }
    }
    function saveUser(user) {
    return database.save(user)
    }
    function sendWelcomeEmail(email) {
    return email.send(email, '欢迎')
    }

    避免副作用

    // 🔶 有副作用:修改外部状态
    let total = 0
    function addToTotal(value) {
    total += value
    }
    // ✅ 纯函数:相同输入总是相同输出
    function add(a, b) {
    return a + b
    }
    // 🔶 修改参数
    function addItem(arr, item) {
    arr.push(item) // 修改了原数组
    return arr
    }
    // ✅ 不修改参数
    function addItem(arr, item) {
    return [...arr, item] // 返回新数组
    }

    总结

    定义方式提升this 绑定arguments适用场景
    函数声明是动态有通用
    函数表达式否动态有回调、条件定义
    箭头函数否继承无回调、简短函数

    核心要点:

    • 函数是一等公民,可以像值一样传递
    • 使用默认参数和剩余参数处理可变参数
    • 箭头函数没有自己的 this 和 arguments
    • 保持函数简短、单一职责、无副作用
    返回 BlogJavaScript
    上一篇控制流语句下一篇对象基础
    Skip toc
    • 🎯 定义函数
      • 函数声明
      • 函数表达式
      • 箭头函数
      • 构造函数
    • 函数参数
      • 基本参数
      • 默认参数
      • 剩余参数
      • arguments 对象
      • 解构参数
    • 返回值
      • return 语句
      • 返回多个值
      • 换行陷阱
    • 函数作用域
      • 词法作用域
      • 变量遮蔽
      • 闭包预览
    • 函数是一等公民
      • 赋值给变量
      • 作为参数传递
      • 作为返回值
      • 存储在数据结构中
    • 立即执行函数(IIFE)
    • 递归函数
    • 函数的属性和方法
      • name 属性
      • length 属性
      • call 和 apply
      • bind
    • 最佳实践
      • 函数命名
      • 单一职责
      • 避免副作用
    • 总结
    Table of Contents
    • 🎯 定义函数
      • 函数声明
      • 函数表达式
      • 箭头函数
      • 构造函数
    • 函数参数
      • 基本参数
      • 默认参数
      • 剩余参数
      • arguments 对象
      • 解构参数
    • 返回值
      • return 语句
      • 返回多个值
      • 换行陷阱
    • 函数作用域
      • 词法作用域
      • 变量遮蔽
      • 闭包预览
    • 函数是一等公民
      • 赋值给变量
      • 作为参数传递
      • 作为返回值
      • 存储在数据结构中
    • 立即执行函数(IIFE)
    • 递归函数
    • 函数的属性和方法
      • name 属性
      • length 属性
      • call 和 apply
      • bind
    • 最佳实践
      • 函数命名
      • 单一职责
      • 避免副作用
    • 总结
    > share on twitter