当前位置: 首页 > news >正文

js代码02

题目

好的,我们继续。

在上一个练习中,我们已经不自觉地接触到了接下来要学习的核心概念:我们将一个函数(箭头函数)作为参数传递给了另一个函数(.filter.map)。这种能力,即把函数当成普通变量一样传来传去,是 JavaScript 强大功能的基础。


练习 02: 函数的力量 - 高阶函数与闭包

这个练习将带你领略 JavaScript 中最深刻、最强大的特性之一。我们将创建一个“函数工厂”,也就是一个能制造其他函数的函数。

🎯 学习目标:

  • 理解“函数是一等公民 (Functions are First-Class Citizens)”的含义。
  • 学会创建并使用“高阶函数 (Higher-Order Function)”。
  • 理解并利用“闭包 (Closure)”的强大特性来记忆状态。

背景知识:

  1. 函数是一等公民: 在 JavaScript 中,函数与其他数据类型(如数字、字符串)地位平等。你可以把它存入变量、作为参数传递给另一个函数,甚至可以作为另一个函数的返回值。
  2. 高阶函数 (Higher-Order Function, HOF): 一个函数如果满足以下至少一个条件,它就是高阶函数:
    • 接受一个或多个函数作为参数(例如我们用过的 .map.filter)。
    • 返回另一个函数。(这是我们本次练习的重点)
  3. 闭包 (Closure): 这是个“魔法”。当一个函数(内部函数)在另一个函数(外部函数)内部被定义时,它就创建了一个闭包。这个闭包使得内部函数有权访问外部函数作用域中的变量,即使在外部函数已经执行完毕之后。换句话-说,内部函数“记住”了它被创建时的环境。

🛠️ 任务:
我们要创建一个名为 createLogger 的函数工厂。这个工厂不直接打印日志,而是根据你提供的“前缀”,生产出专门的日志记录函数。

  1. 创建一个名为 createLogger 的函数,它接受一个字符串参数 prefix
  2. createLogger 函数必须返回一个新的函数
  3. 这个被返回的新函数(我们称之为“日志记录器”)接受一个字符串参数 message
  4. 当调用“日志记录器”时,它应该在控制台打印一条格式化的日志,格式为:[前缀] [时间戳] 消息内容

📋 初始代码:
在你的 js-learning 文件夹中,创建一个新文件 02-higher-order-functions.js,并将以下代码复制进去。你的任务是完成 createLogger 函数的内部实现。

// --- 在这里编写你的代码 ---/*** 创建一个日志记录器函数。* @param {string} prefix - 每条日志消息的前缀。* @returns {function(string): void} - 一个新的函数,该函数接受一个消息字符串并将其记录到控制台。*/
function createLogger(prefix) {// 你的实现需要写在这里。// 关键:你需要从这个函数返回另一个函数。
}// --- 代码结束 ---// --- 使用你创建的函数工厂 ---
// 1. 我们使用 createLogger 工厂创建了三个不同的“日志记录器”实例。
const infoLogger = createLogger("INFO");
const warningLogger = createLogger("WARNING");
const errorLogger = createLogger("ERROR");// 2. 调用这些专门的日志记录器。
infoLogger("Application has started successfully.");
warningLogger("The database connection is getting slow.");
errorLogger("Failed to fetch user data!");// 3. 验证闭包:即使 createLogger 函数已经执行完毕,
//    infoLogger 仍然“记住”了它的前缀是 "INFO"。
infoLogger("This is another informational message.");

💡 要求与提示:

  • createLogger 的核心任务就是 return 一个函数。
  • 被返回的那个内部函数需要同时访问两个变量:一个是外部传入的 prefix,另一个是自己接收的 message
  • 要获取当前时间的 ISO 格式字符串,你可以使用 new Date().toISOString()

✅ 预期输出:
你运行代码后,控制台应该打印出类似下面的内容(时间戳会根据你实际运行的时间而变化):

[INFO] [2025-06-30T14:11:03.456Z] Application has started successfully.
[WARNING] [2025-06-30T14:11:03.457Z] The database connection is getting slow.
[ERROR] [2025-06-30T14:11:03.457Z] Failed to fetch user data!
[INFO] [2025-06-30T14:11:03.458Z] This is another informational message.

这个练习触及了 JavaScript 最强大、最独特的概念之一。慢慢来,仔细思考函数和变量作用域之间的关系。完成后我们来深入探讨!

答案

当然可以!这个概念确实是 JavaScript 中的一个难点,初次接触时感到困惑非常正常。这正是通过看答案和解析来学习的最佳时机。

下面是完整的实现代码。

参考实现 (02-higher-order-functions.js)

/*** 创建一个日志记录器函数。* @param {string} prefix - 每条日志消息的前缀。* @returns {function(string): void} - 一个新的函数,该函数接受一个消息字符串并将其记录到控制台。*/
function createLogger(prefix) {// 这个外部函数的作用域,包含一个我们传入的变量: `prefix`// 关键一步:我们从这个函数返回了“另一个函数”。// 这里我们使用箭头函数语法来定义这个返回的函数。return (message) => {// 闭包的“魔法”在这里发生!// 这个内部函数可以访问它自己的参数 (message)// 同时,它也能访问它“出生环境”中的变量 (prefix)const timestamp = new Date().toISOString();// 它将两者结合起来,打印出完整的日志console.log(`[${prefix}] [${timestamp}] ${message}`);};
}// --- 使用你创建的函数工厂 ---
const infoLogger = createLogger("INFO");
const warningLogger = createLogger("WARNING");
const errorLogger = createLogger("ERROR");infoLogger("Application has started successfully.");
warningLogger("The database connection is getting slow.");
errorLogger("Failed to fetch user data!");infoLogger("This is another informational message.");

深入解析:闭包 (Closure) 如何工作

让我们用一个比喻来彻底理解这段代码。

你可以把 createLogger 函数想象成一个拥有特定模具的“函数制造工厂”

第一步:下订单

当我们执行 const infoLogger = createLogger("INFO"); 这行代码时:

  1. 我们调用了 createLogger 工厂,并给了它一个订单,说:“我想要一个印有 INFO 字样的模具”。
  2. 工厂函数 createLogger 接收到 "INFO",将其存放在名为 prefix 的变量里。
  3. 工厂的核心工作是制造并返回一个新的函数,也就是我们代码里的 (message) => { ... }
  4. 在制造这个新函数的时候,闭包就产生了。这个新函数被赋予了一个神奇的“记忆背包”。它把自己需要用到的、来自工厂环境的“模具”——也就是 prefix 变量(其值为 "INFO")——放进了这个背包里。
  5. 工厂 createLogger 的工作完成了,它把这个刚刚制造出来的、背着“INFO”背包的新函数作为返回值,交给了我们。
  6. 我们用 const infoLogger 这个变量名签收了这个新函数。

现在,infoLogger 变量指向的已经不是工厂了,而是那个专门负责打印 INFO 日志的、有记忆的函数工人

第二步:使用工人

当我们执行 infoLogger("Application has started successfully."); 时:

  1. 我们调用了 infoLogger 这个函数工人。
  2. 我们给了它新的任务信息,也就是 message 参数:“Application has started successfully.”。
  3. 函数工人开始工作。它拿到了新的 message,然后打开它自己的“记忆背包”,找到了当初工厂给它的模具 prefix(值为 "INFO")。
  4. 它把所有信息(prefix、当前时间、message)组装起来,通过 console.log 打印出来。

warningLoggererrorLogger 的创建过程完全一样,只是它们各自的“记忆背包”里分别装着 "WARNING""ERROR" 的模具。它们是三个独立的、拥有不同记忆的函数工人。

回顾我们的学习目标

  • 高阶函数: createLogger 是一个高阶函数,因为它返回了另一个函数。
  • 函数是一等公民: 我们将返回的函数赋值给了 infoLoggerwarningLogger 等变量,证明了函数可以像普通值一样被存储。
  • 闭包: infoLogger 函数记住了它被创建时 prefix 的值是 "INFO",即使在 createLogger 函数早已执行完毕后,这个记忆依然存在。这就是闭包的力量。

你现在已经掌握了 JavaScript 一个非常强大的模式:利用闭包来创建可配置的、可重用的函数,这在各种框架和库中都随处可见。

花点时间消化一下,可以尝试修改代码,比如让 createLogger 再多接收一个参数来控制时间戳的格式等等。

准备好后,我们就可以进入下一个练习,探索另一个核心概念:异步编程

http://www.dtcms.com/a/263486.html

相关文章:

  • NVCC编译以及Triton编译介绍
  • 攻防世界-MISC-red_green
  • 【Python使用】嘿马python运维开发全体系教程第2篇:日志管理,Linux概述【附代码文档】
  • 查看CPU支持的指令集和特性
  • 计算机网络中那些常见的路径搜索算法(一)——DFS、BFS、Dijkstra
  • leetcode:693. 交替位二进制数(数学相关算法题,python3解法)
  • 集群【运维】麒麟V10挂载本地yum源
  • 一套非常完整的复古传奇源码测试
  • LLaMA-Factory框架之参数详解
  • 【机器学习】决策树(Decision Tree)
  • 字节跳动 C++ QT PC客户端面试
  • 设计模式-访问者模式
  • Prompt:提示词工程
  • postgresql增量备份系列二 pg_probackup
  • Linux云计算基础篇(2)
  • ADP3120AJRZ-RL 【ADI】 6A高速MOSFET驱动器,让电源效率飙升!
  • Python-Word文档、PPT、PDF以及Pillow处理图像详解
  • Prompt Enginering
  • django 数据表外键 删除时 对应表的数据不删除如何设置
  • 随笔 | 写在六月的最后一天,也写在2025年上半年的最后一天
  • 2025年6月个人工作生活总结
  • 深入 ARM-Linux 的系统调用世界
  • vue常见问题:
  • 手机APP预约心理咨询师指南
  • 服务器上设置了代理之后,服务器可以访问外网,但是不能访问服务器本地。如何解决
  • CentOS 7 8 安装 madam
  • Android 中 使用 ProgressBar 实现进度显示
  • C++ 安装使用教程
  • MongoDB 安装使用教程
  • Nginx入门