接续上文:Day16(前端:JavaScript基础阶段)_前端题目 csdn-CSDN博客

点关注不迷路哟。你的点赞、收藏,一键三连,是我持续更新的动力哟!!!

主页:一位搞嵌入式的 genius-CSDN博客

系列文章专栏:

https://blog.csdn.net/m0_73589512/category_13011829.html

目录

Day17 (前端:JavaScript基础阶段)

1. 编程领域中 foo、bar、baz 的含义、由来与应用解析

1.1 foo、bar、baz 的核心含义与应用场景

1.2 foo、bar、baz 的起源假说与争议

2. JavaScript 函数基础:概念、使用步骤与核心作用解析

2.1 认识函数:定义、本质与常见内置函数

2.1.1 已接触的 JavaScript 内置函数

2.1.2 函数的核心本质特征

2.2 函数的使用步骤:声明与调用

2.2.1 第一步:声明函数

2.2.2 第二步:调用函数

2.3 函数的核心作用:与循环语句的对比

2.3.1 函数与循环语句的核心对比

2.3.2 函数的核心价值

3. JavaScript 函数基础:声明、调用与实战练习

3.1 函数的声明:语法、规则与注意事项

3.1.1 函数声明的基本语法与结构

3.1.2 函数声明的核心规则与建议

3.1.3 函数声明与调用的基础演练

3.2 函数的调用:方式、机制与位置

3.2.1 函数调用的基本方式

3.2.1 函数调用的核心机制

3.3 函数的实战练习:从固定逻辑到基础应用

3.3.1 练习 1:打印固定个人信息(printInfo 函数)

3.3.2 练习 2:计算并打印固定数字和(sum 函数)

3.4 知识小结:核心考点与难度梳理

4. JavaScript 函数进阶:参数的使用、实战练习与重构优化

4.1 函数参数的基础概念:形参与实参

4.1.1 形参:函数定义时的 “数据占位符”

4.1.2 实参:函数调用时的 “具体数据”

4.1.3 形参与实参的对应关系

4.2 函数参数的实战练习:从单参数到多参数

4.2.1 练习 1:单参数函数 —— 与人打招呼(sayHello 函数)

4.2.2 练习 2:单参数函数 —— 唱生日快乐歌(singBirthdaySong 函数)

4.2.3 练习 3:多参数函数 —— 计算两个数字的和(sum 函数)

4.2.4 练习 4:多参数函数 —— 打印个人信息(printInfo 函数重构)

4.3 知识小结:函数参数的核心考点与难度梳理

4.4 实战建议:函数参数的使用规范

5. JavaScript 函数返回值:概念、return 关键字与实战应用

5.1 函数返回值的基础概念

5.1.1 什么是函数返回值

5.1.2 函数的默认返回值:undefined

5.1.3 基础示例:返回值与外部接收

5.2 return 关键字的核心特性

5.2.1 return 的两大核心功能

5.2.2 return 的关键说明

5.3 函数返回值的三大注意事项

5.3.1 注意事项一:所有无显式 return 的函数均返回 undefined

5.3.2 注意事项二:显式返回 undefined 与默认行为等效

5.3.3 注意事项三:return 的中断效应会跳过后续代码

5.4 函数返回值的实战案例:sum 函数与作用域隔离

5.4.1 案例需求

5.4.2 代码实现

5.4.3 案例关键结论

5.5 知识小结:函数返回值的核心考点

6. JavaScript 函数实战:数字格式化练习与函数间调用解析

6.1 数字格式化的函数练习:从需求到实现

6.1.1 例题:数字格式化的应用场景与转换规则

6.1.2 数字格式化函数的实现与调试

6.2 函数之间的调用:协作逻辑与调试方法

6.2.1 函数之间的调用与调试方法

6.2.2 函数间调用的注意事项

6.3 知识小结:函数实战的核心考点与难度梳理

7. JavaScript 函数的 arguments 对象:特性、应用与 ES6 替代方案

7.1 arguments 参数的基础特性

7.1.1 核心特性解析

7.1.2 关键注意事项

7.2 函数中 arguments 变量的使用方法

7.2.1 基础使用:访问与遍历

7.2.2 核心特点总结

7.3 arguments 的实战案例:不定参求和

7.3.1 案例需求

7.3.2 实现步骤

7.3.3 完整代码

7.3.4 注意事项

7.4 知识小结:arguments 的核心考点与 ES6 过渡

7.5 实战建议:arguments 与剩余参数的选择

8. JavaScript 作用域基础:概念、类型与 ES5 特性解析

8.1 作用域的基本概念与全局作用域

8.1.1 作用域的定义与全局作用域

8.1.2 作用域的 “变量提升” 现象

8.2 ES5 之前的 “无块级作用域” 特性

8.2.1 块级作用域的缺失:var与代码块的关系

8.2.2 控制语句中的作用域表现

8.3 函数作用域:ES5 中唯一的 “局部作用域”

8.3.1 函数作用域的基本特性

8.3.2 嵌套函数的作用域规则

8.4 知识小结:ES5 作用域的核心考点

8.5 核心结论

9. JavaScript 变量类型与访问规则:全局、局部变量及作用域链

9.1 全局变量、局部变量与外部变量的概念

9.1.1 全局变量(Global Variable)

9.1.2 局部变量(Local Variable)

9.1.3 外部变量(Outer Variable)

9.1.4 三类变量的对比总结

9.2 变量的访问顺序:作用域链规则

9.2.1 基本访问规则

9.2.2 例题分析:变量访问顺序的具体表现

例题 1:访问当前函数作用域的变量

例题 2:访问上层作用域的变量

例题 3:访问全局作用域的变量

例题 4:访问 window 对象的变量(全局变量的特殊挂载)

9.3 总结:变量访问的核心逻辑

10. JavaScript 作用域与函数表达式:概念及差异解析

10.1 作用域与变量类型

10.1.1 作用域的核心定义

10.1.2 变量类型及特征

10.1.3 变量访问顺序

10.2 函数表达式:定义与特性

10.2.1 函数表达式的定义

10.2.2 函数声明与函数表达式的区别

10.2.3 开发实践建议

10.3 知识小结:核心考点与难度梳理

10.4 核心结论

11. JavaScript 中的头等函数与函数式编程

11.1 函数的头等公民特性

11.1.1 函数的表达式写法:赋值与传递

11.1.2 函数作为参数、返回值与存储载体

11.1.2.1 函数作为参数传递

11.1.2.2 函数作为返回值

11.1.2.3 函数存储在数据结构中

11.2 函数式编程:理念与语言对比

11.2.1 函数式编程的核心特征

11.2.2 不同语言对函数式编程的支持对比

11.2.3 函数式编程思想的起源与影响

11.3 知识小结:头等函数与函数式编程的核心考点

11.4 核心结论

12. JavaScript 函数式编程核心:头等函数与高阶函数应用

12.1 头等函数的特性与函数式编程基础

12.1.1 头等函数的核心特性

12.1.2 函数式编程的核心场景

12.2 回调函数:异步逻辑的核心机制

12.2.1 回调函数的定义与核心特征

12.2.2 回调函数的实践案例

案例 1:模拟网络请求的回调处理

案例 2:回调函数的正确传递方式

案例 3:匿名函数简化回调逻辑

12.3 高阶函数:接收或返回函数的函数

12.3.1 高阶函数的判定标准

12.3.2 典型示例

12.3.3 内置高阶函数(预告)

12.4 匿名函数:简化回调的临时函数

12.4.1 匿名函数的定义与特点

12.4.2 与函数声明的对比

12.5 知识小结:核心考点与难度梳理

12.6 核心结论


Day17 (前端:JavaScript基础阶段)

1. 编程领域中 foo、bar、baz 的含义、由来与应用解析

在编程实践与技术文档中,foo、bar、baz 是高频出现的占位符名词,广泛用于代码示例、教程及官方资料,尤其在英文技术生态中更为常见。其核心价值在于提供 “无特定含义的通用命名”,避免因具体业务命名引发歧义,确保示例能聚焦技术逻辑本身。后续课程案例中可能直接沿用这类术语,需先明确其本质是编程领域约定俗成的 “伪变量”,而非具有实际业务意义的名称。

1.1 foo、bar、baz 的核心含义与应用场景

foo、bar、baz 是编程领域的标准化占位符,主要用于为函数、变量、文件或类等元素临时命名,本身不承载任何特定功能或业务逻辑,仅作为 “通用代称” 存在。

  • 典型应用示例:在技术问答平台(如 Stack Overflow)、官方文档中,常见类似代码:var foo = 10;(用 foo 作为变量名)、function bar() { return true; }(用 bar 作为函数名),通过极简命名简化示例,让读者专注于代码逻辑而非命名含义;

  • 跨语言通用性:无论前端(JavaScript、HTML)、后端(Java、Python)还是移动端开发,这类占位符均适用,且中文技术文档也常沿用该习惯,需理解其 “约定俗成” 的属性,而非特定语言专属术语。

1.2 foo、bar、baz 的起源假说与争议

foo、bar、baz 的具体起源尚无定论,目前主流假说主要有三类,但均存在一定争议,实际开发中无需深究词源,仅需掌握其应用场景即可:

起源假说核心依据争议点
迪吉多公司手册起源1957 年美国数字设备公司(DEC)的技术手册中首次出现类似占位符缺乏直接文献佐证,手册原文未明确关联 “foo/bar”
电子工程领域衍生可能源于电子学中 “反转信号” 的命名习惯(如 “foo 信号”)跨领域关联性存疑,无明确证据证明技术传承路径
美国漫画文化影响早期美国漫画常用 “foo” 代指 “好运”,发音类似中文 “福”,后被引入编程领域文化传播路径不清晰,缺乏行业共识支持

2. JavaScript 函数基础:概念、使用步骤与核心作用解析

函数是 JavaScript 编程中的核心组件,不仅包含浏览器与语言内置的预定义功能,还支持开发者自定义封装逻辑,是实现代码复用、模块化与灵活执行控制的关键工具。本节从 “认识函数” 入手,梳理函数的本质特征、使用步骤(声明与调用)及与循环语句的差异,建立对函数的基础认知。

2.1 认识函数:定义、本质与常见内置函数

函数本质是 “特定功能代码的封装体”,通过封装实现功能独立、代码可复用,在 JavaScript 中主要分为 “内置预定义函数” 与 “开发者自定义函数” 两类。

2.1.1 已接触的 JavaScript 内置函数

在基础学习阶段,已涉及多个 JavaScript 或浏览器提供的内置函数,其功能与调用方式如下:

  • alert 函数:浏览器内置函数,调用后弹出带有提示信息的弹窗,语法如alert("提示内容")

  • prompt 函数:浏览器内置函数,用于接收用户输入,返回用户输入的字符串(或 null),语法如let input = prompt("请输入内容")

  • console.log 函数:JavaScript 内置函数,需通过console对象调用,用于在控制台输出信息(调试常用),语法如console.log("控制台输出内容")

  • 类型转换函数:JavaScript 内置的基础函数,用于数据类型转换,包括Number(数据)(转为数字)、String(数据)(转为字符串)、Boolean(数据)(转为布尔值)等。

2.1.2 函数的核心本质特征

当讨论 “函数” 时,核心聚焦其以下四个关键特征,这些特征决定了函数的价值与用法:

  1. 功能单一性:每个函数专注实现一个独立功能(如alert仅负责弹窗,Number仅负责类型转换),避免 “一个函数包含多类不相关逻辑”;

  2. 代码封装性:函数内部包裹实现功能的完整代码块,外部调用时无需关注内部逻辑,只需通过 “函数名” 触发执行;

  3. 调用机制:函数不会自动执行,需通过 “函数名 + 括号”(如foo())主动调用,支持在任意需要的时机触发;

  4. 两类来源:既可以使用 JavaScript 或浏览器提供的 “内置函数”,也可以根据业务需求编写 “自定义函数”,灵活适配开发场景。

2.2 函数的使用步骤:声明与调用

使用函数需遵循 “先声明、后调用” 的基本流程(特殊情况如函数表达式可调整顺序,但基础阶段优先掌握 “声明在前”),两个步骤的核心要点与语法规则如下。

2.2.1 第一步:声明函数

函数声明是 “定义函数名称、封装功能代码” 的过程,核心是通过function关键字明确函数的基本信息,关键要点包括:

  • 语法结构:基础语法为function 函数名(参数){ 函数体(功能代码) },例如function sayHello(){ console.log("Hello"); }

  • 命名规则:函数名需遵循 JavaScript 标识符规范(字母、数字、_、$ 组成,不能以数字开头,区分大小写),建议使用 “小驼峰命名法”(如sayHello);

  • 封装范围:函数体({}内的代码)是实现功能的核心,需包含完整的逻辑(如变量定义、条件判断、循环等);

  • 声明位置:在基础阶段,建议将函数声明在调用代码之前,避免因 “变量提升” 机制导致的逻辑混淆;

  • 术语等效:“函数声明”“函数定义”“函数创建” 表达相同含义,均指 “创建函数的过程”。

2.2.2 第二步:调用函数

函数调用是 “触发函数执行、执行封装逻辑” 的过程,只有调用后函数内的代码才会运行,关键特征包括:

  • 执行方式:基础调用语法为 “函数名 + 括号”(如sayHello()),若函数需接收参数,需在括号内传入对应值(如sum(1,2));

  • 调用源:可调用的函数包括三类 ——JavaScript 内置函数(如Number())、浏览器内置函数(如alert())、自定义函数(如sayHello());

  • 调用时机:支持多次重复调用同一函数(如sayHello()可调用 1 次或 100 次),实现代码复用;

  • 术语说明:“函数调用”“函数执行”“函数运行” 表达相同含义,均指 “触发函数代码执行的过程”;

  • 后续扩展:在后续学习框架或第三方库时,会接触 “通过对象调用函数”(如console.log())、“通过类调用函数” 等复杂方式,基础阶段先掌握 “直接调用自定义函数”。

2.3 函数的核心作用:与循环语句的对比

函数的核心价值在于解决 “代码复用”“模块化组织”“灵活执行控制” 等问题,与循环语句(处理固定重复操作)相比,优势显著,具体对比与核心作用如下。

2.3.1 函数与循环语句的核心对比
对比维度循环语句函数
执行时机代码执行到循环时立即顺序执行需通过调用触发,可按需执行
执行复用方式固定次数重复(如for(let i=0;i<5;i++)执行 5 次)无次数限制,可在任意位置调用任意次
代码组织线性流程控制,需嵌入主逻辑模块化封装,独立于主逻辑
核心优势高效处理 “固定次数的重复操作”提高代码复用率与维护性
2.3.2 函数的核心价值
  1. 代码复用:避免对 “相同逻辑” 的重复编写(如多次需要 “弹出欢迎语”,只需声明 1 个sayWelcome函数,多次调用即可);

  2. 功能封装:将复杂逻辑封装为函数,实现 “高内聚、低耦合”(外部只需关注函数能做什么,无需关注内部如何实现);

  3. 执行控制:支持在 “需要时调用”(如用户点击按钮后调用函数),而非 “代码顺序执行”,灵活适配交互场景;

  4. 开发效率:通过模块化拆分代码(将复杂功能拆分为多个小函数),降低代码复杂度,提升开发与维护效率。

3. JavaScript 函数基础:声明、调用与实战练习

函数是 JavaScript 中实现代码复用与逻辑封装的核心工具,其使用需遵循 “先声明、后调用” 的基本流程。本节将从函数声明的语法规则、调用机制入手,结合 “打印个人信息”“计算数字和” 等实战案例,详解函数的基础用法,同时梳理核心知识点与常见易错点,帮助建立函数使用的规范认知。

3.1 函数的声明:语法、规则与注意事项

函数声明是 “定义函数名称、封装功能逻辑” 的第一步,需通过function关键字明确函数结构,同时遵循命名规范与代码执行特点。

3.1.1 函数声明的基本语法与结构

函数声明的核心是通过function关键字搭建框架,包含 “函数名、参数括号、函数体” 三部分,具体结构如下:

  • 关键字:以function开头,明确当前代码块为函数定义;

  • 函数名:用于标识函数(如sayHello),需通过函数名调用函数,区别于for/if等无需命名的代码块;

  • 参数括号:紧跟函数名的(),用于后续接收外部传入的数据(即使暂时无参数,也必须保留空括号,不可省略);

  • 函数体:用{}包裹的代码块,内部是实现函数功能的具体逻辑,代码按自上而下顺序执行。 基础语法示例

function 函数名() {// 函数体:功能实现代码代码逻辑1;代码逻辑2;
}
3.1.2 函数声明的核心规则与建议
  1. 命名规则:

    • 遵循 JavaScript 标识符规范:只能以字母、下划线(_)、美元符号($)开头,后续可包含字母、数字、_$,且区分大小写;

    • 禁止以数字开头(如function 1sayHello(){}为错误写法)。

  2. 命名建议:

    • 使用 “动词 + 名词” 的组合(如printInfo“打印信息”、formatDate“格式化日期”),做到 “见名知意”;

    • 采用小驼峰命名法(首字母小写,后续单词首字母大写,如sayHelloWorld),符合 JavaScript 开发习惯。

  3. 执行特点:

    • 函数声明后不会自动执行,仅完成 “功能定义”(类似 “制作工具但不使用”),必须通过后续调用触发代码执行;

    • 函数体内部代码在未调用时,不会参与页面的顺序执行。

  4. 代码规范:

    • 函数名与参数括号之间建议保留 1 个空格(如function sayHello (),而非function sayHello());

    • 参数括号与函数体大括号之间建议保留 1 个空格(如function sayHello () {,而非function sayHello (){),提升代码可读性。

3.1.3 函数声明与调用的基础演练

sayHello函数为例,演示函数从声明到调用的完整流程:

// 1. 声明函数:定义“打印问候语”的功能
function sayHello () {console.log("Hello!");console.log("My name is Coderwhy!");console.log("how do you do!");
}
​
// 2. 调用函数:通过“函数名+括号”触发执行(可多次调用)
sayHello(); // 第一次调用:执行函数体,控制台输出3行问候语
sayHello(); // 第二次调用:再次执行函数体,控制台重复输出3行问候语

关键结论:同一函数可被多次调用,每次调用都会完整执行函数体内的所有代码,实现 “一次声明、多次复用”。

3.2 函数的调用:方式、机制与位置

函数调用是 “触发函数执行” 的关键步骤,只有通过调用,函数体内的逻辑才会运行,需掌握调用方式与执行机制。

3.2.1 函数调用的基本方式

函数调用的基础语法为 “函数名 + 空括号”(无参数时),具体格式:

函数名(); // 如sayHello();、printInfo();
  • 即使函数体内部无任何参数依赖(如sayHello仅打印固定内容),括号也不可省略(sayHello为函数本身,sayHello()才是调用函数);

  • 调用时会按照函数体内部代码的顺序,依次执行每条语句(如console.log会按顺序输出)。

3.2.1 函数调用的核心机制
  1. 执行时机:函数仅在 “调用时” 执行,未调用时,函数体代码处于 “休眠状态”,不占用执行资源;

  2. 调用位置:

    • 需在函数声明之后调用(基础阶段避免 “先调用、后声明”,防止因 “变量提升” 导致逻辑混淆);

    • 需在函数的 “作用域范围内” 调用(如全局声明的函数可在全局任意位置调用,后续会学习局部函数的调用限制);

  3. 多次调用的效果:每次调用都是独立的执行过程,函数体内的临时变量(如后续案例中的result)会在每次调用时重新初始化,互不影响。

示例:多次调用sayHello函数的执行效果

function sayHello () {let count = 1; // 每次调用时,count都会重新初始化为1console.log("调用次数标记:", count);count++;
}
​
sayHello(); // 输出“调用次数标记:1”
sayHello(); // 仍输出“调用次数标记:1”(count重新初始化)
3.3 函数的实战练习:从固定逻辑到基础应用

通过两个基础案例,掌握函数在实际场景中的使用,理解 “封装固定逻辑、实现灵活复用” 的核心价值。

3.3.1 练习 1:打印固定个人信息(printInfo 函数)

需求:封装一个函数,调用后在控制台打印固定的个人信息(姓名、年龄、身高)。 实现代码

// 声明函数:封装“打印个人信息”的逻辑
function printInfo () {console.log("my name is why");console.log("age is 18"); console.log("height is 1.88");
}
​
// 调用函数:触发信息打印
printInfo(); // 控制台依次输出3行个人信息

优势分析: 相比直接在代码中写 3 条console.log,函数封装的优势在于 “可复用”—— 若后续需要多次打印该信息,只需调用printInfo(),无需重复编写 3 行输出代码,减少冗余。

3.3.2 练习 2:计算并打印固定数字和(sum 函数)

需求:封装一个函数,计算 10 与 20 的和,并在控制台打印结果。 实现代码

// 声明函数:封装“计算固定值和并打印”的逻辑
function sum () {let number1 = 10; // 固定第一个数字let number2 = 20; // 固定第二个数字let result = number1 + number2; // 计算和console.log("result:", result); // 打印结果
}
​
// 调用函数:触发计算与打印
sum(); // 控制台输出“result: 30”

局限性说明: 当前函数只能计算 “10+20” 的固定结果,无法动态接收外部传入的数字(如计算 “5+8”“20+30”),后续将通过 “函数参数” 解决该问题,让函数更灵活。

3.4 知识小结:核心考点与难度梳理
知识点核心内容考试重点 / 易混淆点难度系数
函数声明与调用function关键字声明函数(含函数名、参数括号、代码块);通过 “函数名 ()`” 调用函数名命名规则(与变量一致,但推荐动词开头);调用时不可省略括号(sayHellosayHello()⭐⭐
函数命名规范遵循标识符规则(不以数字开头);推荐 “动词 + 名词”“小驼峰” 写法特殊函数名的例外情况(如isNaN,虽以字母开头但为 “判断 + 名词” 结构)
函数执行机制声明后不自动执行,需显式调用;每次调用完整执行函数体for/if代码块 “自动执行” 的区别(for满足条件即执行,函数需主动调用)⭐⭐
参数与返回值(基础)小括号用于后续传递参数;当前案例无参数仍可运行;结果通过console.log输出无参数时必须保留空括号(不可省略);当前函数仅 “打印结果”,未实现 “返回结果”⭐⭐⭐
函数复用性可多次调用同一函数,实现代码复用;调用次数无限制需在函数作用域内调用(后续讲解作用域);多次调用时临时变量重新初始化⭐⭐
练习案例 1(printInfo)打印固定个人信息;优势是减少重复输出代码硬编码数据导致灵活性不足(无法动态修改姓名、年龄)
练习案例 2(sum)计算固定值(10+20)并打印;体现函数封装逻辑的基础用法缺乏参数传递,无法动态计算不同数字的和;需后续学习参数解决该问题⭐⭐

4. JavaScript 函数进阶:参数的使用、实战练习与重构优化

函数参数是提升函数通用性的核心工具,通过将 “固定值” 替换为 “参数占位符”,可让函数灵活处理不同输入数据,适配更多业务场景。本节从函数参数的基础概念(形参、实参)入手,结合 “打印个人信息”“打招呼”“计算数字和” 等实战案例,详解参数化函数的改造与使用方法,同时梳理核心知识点与易错点,帮助掌握函数从 “固定逻辑” 到 “通用工具” 的进阶技巧。

4.1 函数参数的基础概念:形参与实参

函数参数分为 “形参(parameter)” 与 “实参(argument)”,二者分别对应 “函数定义时的占位符” 与 “函数调用时的具体数据”,是实现函数通用化的关键。

4.1.1 形参:函数定义时的 “数据占位符”
  • 核心定义:在函数声明时,写在()内的变量名称,用于接收函数调用时传入的数据,本质是 “函数内部的临时变量”;

  • 作用:为函数预留 “数据入口”,避免函数内部硬编码固定值,使函数能处理不同输入;

  • 语法示例:在function printInfo(name, age, height) {}中,nameageheight均为形参,分别对应 “姓名”“年龄”“身高” 的占位符;

  • 注意事项:形参仅在函数内部有效,函数外部无法访问;若函数无需接收数据,()内可留空(但不可省略())。

4.1.2 实参:函数调用时的 “具体数据”
  • 核心定义:在函数调用时,写在()内的具体值(如数字、字符串、变量等),用于传递给函数的形参;

  • 作用:为形参赋值,让函数根据实际输入执行逻辑;

  • 语法示例:在printInfo("why", 18, 1.88)中,"why"(字符串)、18(数字)、1.88(数字)均为实参,分别对应nameageheight三个形参;

  • 注意事项:实参的数量、类型需与形参匹配(基础阶段),否则可能导致函数逻辑异常(如形参需数字,实参传字符串可能引发计算错误)。

4.1.3 形参与实参的对应关系
  • 顺序对应:实参按 “从左到右” 的顺序依次赋值给形参,第一个实参对应第一个形参,第二个实参对应第二个形参,以此类推;

  • 数量匹配:

    • 若实参数量 = 形参数量:正常赋值,函数按预期执行;

    • 若实参数量 < 形参数量:未匹配的形参值为undefined(如printInfo("why", 18)中,heightundefined);

    • 若实参数量 > 形参数量:多余实参不赋值给形参,但可通过arguments对象(后续学习)访问;

  • 示例验证:

    // 声明函数:3个形参(name, age, height)
    function printInfo(name, age, height) {console.log("姓名:", name);console.log("年龄:", age);console.log("身高:", height);
    }
    ​
    // 调用函数:3个实参,与形参完全匹配
    printInfo("why", 18, 1.88); 
    // 输出:姓名:why → 年龄:18 → 身高:1.88
    ​
    // 调用函数:2个实参,height未赋值(为undefined)
    printInfo("小明", 20); 
    // 输出:姓名:小明 → 年龄:20 → 身高:undefined
4.2 函数参数的实战练习:从单参数到多参数

通过不同类型的实战案例,掌握 “单参数函数”“多参数函数” 的定义与调用,理解参数如何提升函数通用性。

4.2.1 练习 1:单参数函数 —— 与人打招呼(sayHello 函数)

需求:定义一个函数,传入一个 “姓名” 参数,调用后打印 “Hello, [姓名]!” 的问候语,实现对不同人的个性化问候。 实现步骤

  1. 声明函数:定义形参name,接收传入的姓名;

  2. 编写逻辑:在函数体内,通过模板字符串拼接姓名与问候语;

  3. 调用函数:传入不同姓名作为实参,验证函数通用性。 代码示例

// 1. 声明函数:单形参name
function sayHello(name) {// 使用模板字符串拼接动态姓名console.log(`Hello, ${name}!`);
}
​
// 2. 调用函数:传入不同实参,实现个性化问候
sayHello("why");    // 输出:Hello, why!
sayHello("小明");   // 输出:Hello, 小明!
sayHello("Alice");  // 输出:Hello, Alice!

核心价值:相比 “固定打印 Hello, why!” 的函数,通过参数name,函数可灵活适配任意姓名,通用性显著提升。

4.2.2 练习 2:单参数函数 —— 唱生日快乐歌(singBirthdaySong 函数)

需求:定义一个函数,传入一个 “姓名” 参数,调用后打印包含该姓名的生日歌歌词,实现为不同人 “唱” 生日歌。 实现代码

function singBirthdaySong(name) {console.log(`祝你生日快乐,${name}!`);console.log(`祝你生日快乐,${name}!`);console.log(`祝你幸福祝你健康,${name}!`);console.log(`祝你生日快乐!`);
}
​
// 调用函数:传入不同姓名
singBirthdaySong("why");  // 为why唱生日歌
singBirthdaySong("小红"); // 为小红唱生日歌

技巧:通过模板字符串(反引号+${变量})实现 “固定歌词模板 + 动态姓名” 的结合,既保留固定格式,又支持个性化输入。

4.2.3 练习 3:多参数函数 —— 计算两个数字的和(sum 函数)

需求:定义一个函数,传入两个 “数字” 参数,调用后计算并打印它们的和,替代之前 “只能计算 10+20” 的固定函数。 实现步骤

  1. 声明函数:定义两个形参num1num2,分别接收两个待加数字;

  2. 编写逻辑:在函数体内计算num1 + num2,并打印结果;

  3. 调用函数:传入不同数字组合作为实参,验证函数通用性。 代码示例:

// 1. 声明函数:两个形参num1、num2
function sum(num1, num2) {const result = num1 + num2; // 计算和console.log(`${num1} + ${num2} = ${result}`);
}
​
// 2. 调用函数:传入不同数字组合
sum(10, 20);   // 输出:10 + 20 = 30
sum(5, 8);     // 输出:5 + 8 = 13
sum(100, 250); // 输出:100 + 250 = 350

重构价值:相比之前 “硬编码 num1=10、num2=20” 的函数,多参数设计让函数可计算任意两个数字的和,从 “专用工具” 变为 “通用加法器”。

4.2.4 练习 4:多参数函数 —— 打印个人信息(printInfo 函数重构)

需求:重构之前 “只能打印固定信息” 的printInfo函数,通过传入 “姓名、年龄、身高” 三个参数,实现打印不同人的信息。 代码示例

// 重构后的函数:三个形参,接收不同人的信息
function printInfo(name, age, height) {console.log("=== 个人信息 ===");console.log(`姓名:${name}`);console.log(`年龄:${age}岁`);console.log(`身高:${height}米`);console.log("=================");
}
​
// 调用函数:传入不同人的信息
printInfo("why", 18, 1.88);
// 输出:=== 个人信息 === → 姓名:why → 年龄:18岁 → 身高:1.88米 → =================
​
printInfo("小明", 20, 1.75);
// 输出:=== 个人信息 === → 姓名:小明 → 年龄:20岁 → 身高:1.75米 → =================

关键改进:通过参数替换硬编码值,函数从 “只能打印 why 的信息” 变为 “可打印任意人的信息”,复用性大幅提升,后续如需新增人物信息,只需新增一次调用即可。

4.3 知识小结:函数参数的核心考点与难度梳理
知识点核心内容考试重点 / 易混淆点难度系数
函数声明与调用基础语法:function 函数名(形参){...};调用:函数名(实参)函数名命名规范(动词开头);调用时不可省略();形参未赋值时为undefined⭐⭐
函数参数概念形参(定义时的占位符)与实参(调用时的具体值);按顺序匹配形参与实参的数量不匹配问题(实参少则形参为undefined,实参多则多余值不赋值);“parameter” 与 “argument” 的英文对应关系⭐⭐⭐
参数化函数改造将函数内的固定值抽取为形参,提升函数通用性;如 sum 函数从固定 10+20 改为通用加法参数抽取的边界判断(哪些值适合作为参数,哪些适合保留为固定值);默认值的简要理解(后续深入)⭐⭐⭐⭐
字符串拼接技巧使用模板字符串(${变量})拼接动态内容,替代传统+拼接模板字符串与传统拼接的区别(模板字符串支持换行、直接嵌入变量);性能差异(现代浏览器中差异极小,优先考虑可读性)⭐⭐
函数重构案例(printInfo)从固定输出改造为多参数动态输出,实现打印任意人的信息多参数传递时的顺序对应(实参顺序必须与形参一致,否则信息错位);参数类型的隐性要求(如年龄需传数字)⭐⭐⭐
数学运算函数(sum)多参数实现通用加法,计算任意两个数字的和参数类型校验(如实参传字符串 “10” 与数字 20,会触发字符串拼接而非加法);隐式类型转换对结果的影响⭐⭐⭐
单参数函数(sayHello/singBirthdaySong)单形参实现个性化问候 / 祝福,适配不同输入单参数的使用场景边界(适合仅需一个动态值的场景);参数名的语义化(如用name而非x⭐⭐
ES6 默认参数(简要提及)基础语法:function fn(a=10){...},为形参设置默认值兼容性考虑(IE 不支持,需用 `a = a10替代);默认值的生效时机(实参为undefined` 时触发)⭐⭐⭐⭐
4.4 实战建议:函数参数的使用规范
  1. 参数名语义化:形参名需体现数据含义(如用name而非nage而非a),提升代码可读性;

  2. 控制参数数量:单个函数的参数建议不超过 3-4 个,过多参数会导致调用时易混淆顺序,可通过对象(后续学习)整合多个相关参数;

  3. 明确参数类型:在函数内可添加简单的类型校验(如if (typeof num1 !== "number") { alert("请传入数字"); }),避免因参数类型错误导致逻辑异常;

  4. 优先使用模板字符串:拼接动态内容时,优先用模板字符串(${变量}),替代传统+拼接(如"Hello, " + name + "!"),减少语法错误(如遗漏引号、加号)。

5. JavaScript 函数返回值:概念、return 关键字与实战应用

函数返回值是函数与外部代码交互的核心桥梁 —— 通过返回值,函数可将内部处理结果传递给外部,供后续逻辑使用(如计算结果、格式化数据)。默认情况下,函数执行后返回undefined,若需返回特定结果,需通过return关键字显式定义。本节将从返回值的基础概念入手,详解return的核心特性、注意事项及实战案例,帮助掌握函数 “输出结果” 的关键逻辑。

5.1 函数返回值的基础概念

函数返回值指 “函数执行完成后,传递给调用者的结果”,是函数实现 “数据输出” 的唯一方式,需先明确其默认行为与基础特征。

5.1.1 什么是函数返回值

函数的核心作用分为 “处理逻辑” 与 “输出结果”:

  • “处理逻辑”:函数体内的代码(如计算、打印、数据转换);

  • “输出结果”:函数执行后对外提供的结果,即返回值。 例如浏览器内置的prompt()函数,执行后会返回用户输入的字符串;自定义的 “计算和” 函数,执行后可返回两个数字的和,供外部变量接收或进一步运算。

5.1.2 函数的默认返回值:undefined

若函数未通过return显式指定返回值,执行后默认返回undefined(无论函数体内是否有其他逻辑,如打印、变量定义)。 示例 1:无 return 的函数返回 undefined

// 函数1:仅打印内容,无return
function sayHello() {console.log("Hello World");
}
​
// 调用函数并接收返回值
const foo = sayHello(); 
console.log(foo); // 输出:undefined(默认返回值)
​
// 函数2:空函数(无任何逻辑)
function emptyFunc() {}
const bar = emptyFunc();
console.log(bar); // 输出:undefined(默认返回值)
5.1.3 基础示例:返回值与外部接收

通过return指定返回值后,外部可通过 “变量赋值” 接收结果,实现 “函数内部逻辑” 与 “外部使用” 的联动。 示例:模板字符串拼接与返回值

// 函数:接收姓名,返回拼接后的问候语
function getGreeting(name) {// 通过return返回模板字符串结果return `Hello ${name}`;
}
​
// 外部接收返回值
const greeting = getGreeting("why");
console.log(greeting); // 输出:Hello why(使用返回值)
// 进一步使用返回值(如插入DOM)
document.body.textContent = greeting;
5.2 return 关键字的核心特性

return是控制函数返回值与执行流程的关键关键字,兼具 “返回结果” 与 “终止函数” 两大功能,需重点掌握其使用规则。

5.2.1 return 的两大核心功能
  1. 功能 1:返回指定结果 return后可跟任意类型的值(数字、字符串、变量、对象等),该值会作为函数的返回值传递给外部。 示例:返回变量或字面量:

    // 示例1:返回变量(两数之和)
    function sum(num1, num2) {const result = num1 + num2;return result; // 返回变量result
    }
    const total = sum(10, 20);
    console.log(total); // 输出:30
    ​
    // 示例2:返回字面量(直接返回固定值)
    function getFixedValue() {return 123; // 返回数字字面量
    }
    console.log(getFixedValue()); // 输出:123
  2. 功能 2:终止函数执行 函数执行到return语句时,会立即停止后续代码的执行(无论return后是否有其他逻辑),即 “return后的代码不会运行”。 示例:return 的中断效应

    function baz() {console.log("执行到return前");return "终止信号"; // 执行到此处,函数立即终止console.log("执行到return后"); // 该代码不会执行(被中断)
    }
    ​
    const result = baz();
    console.log(result); // 输出:执行到return前 → 终止信号(return后的打印未执行)
5.2.2 return 的关键说明
关键点具体规则与示例
无值返回的 returnreturn后不跟任何值(仅return;),等效于return undefined,函数返回undefined。 示例:function fn() { return; } console.log(fn()); // undefined
return 的位置限制return仅能在函数体内使用,在函数体外使用会触发语法错误。 错误示例:return 123; // Uncaught SyntaxError: Illegal return statement
返回值的类型灵活性return可返回任意 JavaScript 类型(数字、字符串、数组、对象、甚至函数),无类型限制。 示例:function getObj() { return { name: "why" }; } console.log(getObj().name); // why
5.3 函数返回值的三大注意事项

在使用函数返回值时,需关注 “默认行为”“中断效应”“显式与隐式返回的等效性”,避免因理解偏差导致逻辑错误。

5.3.1 注意事项一:所有无显式 return 的函数均返回 undefined

无论函数体内包含多少逻辑(如循环、条件判断、打印),只要未通过return显式指定返回值,最终返回结果均为undefined示例验证

// 函数:包含条件判断与打印,无return
function checkAge(age) {if (age >= 18) {console.log("成年人");} else {console.log("未成年人");}
}
​
const result = checkAge(20);
console.log(result); // 输出:成年人 → undefined(无显式return,默认返回undefined)
5.3.2 注意事项二:显式返回 undefined 与默认行为等效

以下三种情况,函数返回值均为undefined,效果完全一致:

  1. 函数体内无return语句;

  2. 函数体内仅写return;(无后续值);

  3. 函数体内写return undefined;(显式返回undefined)。 示例对比

// 情况1:无return
function fn1() {}
// 情况2:return后无值
function fn2() { return; }
// 情况3:显式return undefined
function fn3() { return undefined; }
​
console.log(fn1()); // undefined
console.log(fn2()); // undefined
console.log(fn3()); // undefined(三者效果一致)
5.3.3 注意事项三:return 的中断效应会跳过后续代码

函数执行到return时会立即终止,无论return后是否有重要逻辑(如数据修改、打印、函数调用),均不会执行。开发中需避免将关键逻辑写在return之后。 错误示例与修正

// 错误示例:return后的console.log不会执行
function calculate(num1, num2) {const sum = num1 + num2;return sum; // 函数在此终止console.log("计算完成"); // 永远不会执行
}
​
// 正确示例:将关键逻辑放在return之前
function calculate(num1, num2) {const sum = num1 + num2;console.log("计算完成"); // 先执行打印return sum; // 再返回结果
}
​
calculate(10, 20); // 输出:计算完成 → 返回30
5.4 函数返回值的实战案例:sum 函数与作用域隔离

通过 “计算两数之和” 的实战案例,进一步理解返回值的使用场景,以及函数 “作用域隔离” 的特性(函数内外同名变量互不影响)。

5.4.1 案例需求

定义sum函数,接收两个数字参数,计算它们的和并通过return返回结果;外部通过变量接收返回值,并打印结果。

5.4.2 代码实现
// 1. 定义sum函数:接收参数,返回两数之和
function sum(num1, num2) {// 函数内部变量result(局部变量)const result = num1 + num2;return result; // 返回计算结果
}
​
// 2. 外部使用:接收返回值,定义同名变量result(全局变量)
const result = sum(15, 25); // 接收返回值30
console.log("两数之和:", result); // 输出:两数之和:30
​
// 3. 验证作用域隔离:函数内外同名变量互不影响
function testScope() {const message = "函数内部变量";return message;
}
​
const message = "函数外部变量";
console.log(testScope()); // 输出:函数内部变量(返回内部变量)
console.log(message);     // 输出:函数外部变量(外部变量未被修改)
5.4.3 案例关键结论
  1. 返回值的接收与使用:外部通过 “变量 = 函数调用” 的形式接收返回值,后续可用于打印、运算、DOM 操作等场景;

  2. 作用域隔离:函数内部定义的变量(如sum中的result)仅在函数体内有效,与外部同名变量(如全局result)互不干扰,这是函数 “封装性” 的重要体现;

  3. 返回值的灵活性:

    return

    可直接返回计算结果(如

    return num1 + num2

    ),无需额外定义局部变量,简化代码:

    // 简化版sum函数:直接返回计算结果
    function sum(num1, num2) {return num1 + num2; // 无需定义result变量
    }
5.5 知识小结:函数返回值的核心考点
知识点核心内容考试重点 / 易混淆点难度系数
函数返回值基础概念函数执行后传递给外部的结果;默认返回undefined,显式返回需用returnreturn的函数与return;的函数返回值一致(均为undefined);返回值与 “打印” 的区别(打印是输出到控制台,返回值是传递给外部)⭐⭐
return 关键字的功能两大功能:返回指定值、终止函数执行;可返回任意类型数据return后的代码不执行(中断效应);return在函数体外使用会报错;return后无值等效于return undefined⭐⭐⭐
函数返回值的注意事项无显式 return 则返回undefined;显式返回undefined与默认行为等效;return中断函数误将关键逻辑写在return之后;混淆 “返回值” 与 “控制台输出”(如认为console.log会影响返回值)⭐⭐⭐
实战案例(sum 函数)接收参数计算和,返回结果;外部接收并使用;函数内外变量作用域隔离作用域隔离特性(同名变量互不影响);简化写法(直接返回计算结果,无需局部变量)⭐⭐
返回值的应用场景传递计算结果、格式化数据(如formatCount函数)、提供判断依据不同类型返回值的使用(如返回对象时,外部可直接访问对象属性);返回值的链式使用(如sum(10,20) + 5⭐⭐⭐

6. JavaScript 函数实战:数字格式化练习与函数间调用解析

在实际开发中,函数不仅用于封装基础逻辑,还需解决具体业务场景(如数字格式化),同时涉及函数间的协作调用。本节将围绕 “数字格式化” 这一高频需求,详解函数的实战实现、调试技巧,同时梳理函数间调用的核心方法与注意事项,帮助将函数知识落地到实际业务中。

6.1 数字格式化的函数练习:从需求到实现

数字格式化是前端常见需求(如播放量、点赞数显示),核心是将大数字(如 5433322)转换为 “万 / 亿” 单位的易读文本,需通过函数封装转换逻辑,确保通用性与可维护性。

6.1.1 例题:数字格式化的应用场景与转换规则

数字格式化的核心目标是 “优化大数字的可读性”,需先明确需求背景、必要性与转换逻辑:

  1. 应用场景 常见于音乐平台(如网易云音乐播放量)、社交平台(点赞数)、电商平台(销量)等,例如将 “5433322 次播放” 显示为 “543 万次播放”。

  2. 必要性

    • 直接显示大数字(如 8766633333)会导致界面拥挤,影响美观;

    • 用户难以快速感知数字量级(如 “5433322” 需数位数判断是 “百万级”,而 “543 万” 可瞬间理解)。

  3. 核心转换规则

    数字范围转换方式示例
    小于 10 万(<100000)直接显示原数字13687 → 13687
    10 万~10 亿(100000 ≤ 数字 < 1000000000)转换为 “万” 单位,向下取整5433322 → 543 万(5433322 ÷ 10000 = 543.3322,向下取整为 543)
    大于等于 10 亿(≥1000000000)转换为 “亿” 单位,向下取整8766633333 → 87 亿(8766633333 ÷ 100000000 = 87.66633333,向下取整为 87)
6.1.2 数字格式化函数的实现与调试

基于转换规则,封装formatCount函数,核心需解决 “量级判断”“单位计算”“结果拼接” 三大问题,同时通过调试技巧确保逻辑正确性。

  1. 函数实现步骤

    • 步骤 1:处理数字量级判断:用if-else判断数字属于 “小于 10 万”“10 万~10 亿”“≥10 亿” 中的哪一类;

    • 步骤 2:单位计算与向下取整:用Math.floor()对 “数字 ÷ 单位基数”(10000 或 100000000)向下取整,避免小数;

    • 步骤 3:结果拼接:将取整后的数字与对应单位(空 /“万”/“亿”)拼接,返回最终字符串;

    • ES6 特性优化:用数字分隔符_(如10_0000表示 10 万、10_0000_0000表示 10 亿)提高代码可读性,避免因多位数导致的计数错误。

    完整代码

    // 数字格式化函数:将大数字转换为"万/亿"单位的易读文本
    function formatCount(count) {// 1. 小于10万:直接返回原数字(转为字符串,保持格式统一)if (count < 10_0000) {return count.toString();} // 2. 10万~10亿:转换为"万"单位else if (count < 10_0000_0000) {const result = Math.floor(count / 10_000); // 向下取整,避免小数return `${result}万`;} // 3. 大于等于10亿:转换为"亿"单位else {const result = Math.floor(count / 10_0000_0000);return `${result}亿`;}
    }
  2. 测试用例验证 通过典型案例测试函数逻辑,确保边界值(如 10 万、10 亿)处理正确:

    // 测试用例1:小于10万
    console.log(formatCount(13687)); // 输出:"13687"
    // 测试用例2:10万~10亿(边界值10万)
    console.log(formatCount(10_0000)); // 输出:"10万"
    console.log(formatCount(5433322)); // 输出:"543万"
    // 测试用例3:≥10亿(边界值10亿)
    console.log(formatCount(10_0000_0000)); // 输出:"10亿"
    console.log(formatCount(8766633333)); // 输出:"87亿"
  3. 调试技巧 若函数返回结果异常(如边界值处理错误),可通过以下方法排查:

    • 断点调试:在函数内添加

      debugger

      语句,打开浏览器开发者工具(Sources 面板),逐步执行查看变量值变化:

      function formatCount(count) {debugger; // 断点:执行到此时暂停,可查看count值、分支判断结果if (count < 10_0000) {return count.toString();} else if (count < 10_0000_0000) {const result = Math.floor(count / 10_000);return `${result}万`;} else {const result = Math.floor(count / 10_0000_0000);return `${result}亿`;}
      }
    • 常见错误排查:

      1. 函数名拼写错误(如formatCount误写为fomartCount),导致调用失败;

      2. 单位基数计算错误(如将 “万” 的基数写为1000而非10000);

      3. 忘记返回结果(如漏写return,导致函数默认返回undefined);

      4. 未用Math.floor()取整,导致结果出现小数(如5433322 → 543.3322万)。

6.2 函数之间的调用:协作逻辑与调试方法

在复杂业务中,单个函数无法完成所有需求,需多个函数协作(如 “获取原始数据→格式化数据→渲染界面”),需掌握函数间调用的执行顺序、调试技巧与注意事项。

6.2.1 函数之间的调用与调试方法

函数间调用的核心是 “一个函数内部调用另一个函数”,通过返回值传递数据,形成协作流程。以 “获取播放量→格式化→打印” 为例:

  1. 协作函数示例:

    // 函数1:模拟从服务器获取原始播放量(模拟数据)
    function getRawPlayCount() {// 模拟服务器返回的大数字return 8766633333;
    }
    ​
    // 函数2:数字格式化函数(复用6.1.2中的formatCount)
    function formatCount(count) {if (count < 10_0000) {return count.toString();} else if (count < 10_0000_0000) {return `${Math.floor(count / 10_000)}万`;} else {return `${Math.floor(count / 10_0000_0000)}亿`;}
    }
    ​
    // 函数3:主函数(调用前两个函数,完成“获取→格式化→打印”流程)
    function showFormattedPlayCount() {// 步骤1:调用getRawPlayCount,获取原始数据const rawCount = getRawPlayCount();// 步骤2:调用formatCount,格式化数据(传递rawCount作为实参)const formattedCount = formatCount(rawCount);// 步骤3:打印结果console.log(`歌曲播放量:${formattedCount}次`);
    }
    ​
    // 执行主函数,触发整个流程
    showFormattedPlayCount(); // 输出:"歌曲播放量:87亿次"
  2. 调试方法:查看调用栈(Call Stack) 函数间调用时,浏览器会记录 “函数调用的顺序”(即调用栈),可通过开发者工具排查执行顺序与变量值:

    • 打开浏览器开发者工具(F12),切换到Sources面板;

    • 在主函数showFormattedPlayCount内添加debugger,执行函数;

    • 暂停后,查看右侧

      Call Stack

      面板,会显示函数调用顺序(从下到上为调用顺序):

      • showFormattedPlayCount(主函数,当前执行);

      • formatCount(被showFormattedPlayCount调用);

      • getRawPlayCount(被showFormattedPlayCount调用);

    • 点击调用栈中的函数,可查看该函数执行时的变量值(如rawCountformattedCount),快速定位错误。

6.2.2 函数间调用的注意事项
  1. 避免函数名与内部变量名重复 若函数名与内部变量名一致,会导致变量覆盖函数,无法正常调用。例如:

    // 错误示例:函数名formatCount与内部变量名formatCount重复
    function formatCount(count) {const formatCount = count / 10_000; // 变量覆盖函数return `${formatCount}万`;
    }
    formatCount(5433322); // 报错:formatCount is not a function(变量覆盖后,formatCount变为数字,非函数)

    修正:变量名需与函数名区分(如const formattedNum = count / 10_000)。

  2. 确保所有分支都有返回值 若函数存在多分支(如if-else),需确保每个分支都有return,避免部分场景下函数默认返回undefined。例如:

    // 错误示例:缺少“小于10万”分支的return
    function formatCount(count) {if (count < 10_0000) {count.toString(); // 漏写return,该分支无返回值} else if (count < 10_0000_0000) {return `${Math.floor(count / 10_000)}万`;}
    }
    console.log(formatCount(13687)); // 输出:undefined(无返回值)

    修正:所有分支必须添加return(如return count.toString())。

  3. 注意大型数字的范围限制 JavaScript 中数字有最大安全值(Number.MAX_SAFE_INTEGER = 9007199254740991,约 9007 亿),若处理的数字超过该值(如 1 万亿),会导致精度丢失,需用BigInt类型处理:

    // 处理超大数字(如1.2万亿),用BigInt类型
    function formatBigCount(count) {// 转换为BigInt,避免精度丢失const bigCount = BigInt(count);if (bigCount < 10_0000n) { // 数字后加n,表示BigIntreturn bigCount.toString();} else if (bigCount < 10_0000_0000n) {return `${bigCount / 10_000n}万`;} else {return `${bigCount / 10_0000_0000n}亿`;}
    }
    console.log(formatBigCount("1200000000000")); // 输出:"1200亿"
6.3 知识小结:函数实战的核心考点与难度梳理
知识点核心内容考试重点 / 易混淆点难度系数
数字格式化函数封装formatCount函数,将大数字按 “10 万 / 10 亿” 分界,转换为 “万 / 亿” 单位文本边界值处理(如 10 万、10 亿的判断条件是否正确);Math.floor()的作用(避免小数)⭐⭐
工具函数封装按 “单一职责” 原则封装通用函数(如数字格式化),提高复用性与维护性函数命名规范(如formatCount体现 “功能 + 数据类型”);函数内外变量的作用域隔离⭐⭐
数字类型处理使用 ES6 数字分隔符_提高大数字可读性;超大数字用BigInt避免精度丢失数字分隔符的语法(如10_0000而非100000);Math.floor()Math.round()的区别(向下取整 vs 四舍五入)
实际应用场景前端显示优化(播放量、销量等),将服务器返回的原始大数字转换为易读格式服务器原始数据(数字类型)与前端显示格式(字符串类型)的转换逻辑;用户体验优先的设计思路⭐⭐⭐
调试技巧debugger断点调试,查看调用栈与变量值;排查函数名拼写、返回值缺失等错误调用栈的解读(从下到上为调用顺序);变量覆盖函数的错误排查(函数名与变量名重复)⭐⭐⭐
工程化思维通用工具函数的封装原则(单一职责、无副作用);函数间协作的流程设计函数纯度(输入相同则输出相同,无副作用);避免函数间过度耦合(如减少硬编码依赖)⭐⭐⭐⭐

7. JavaScript 函数的 arguments 对象:特性、应用与 ES6 替代方案

在 JavaScript 函数中,arguments是一个特殊的内置对象,用于存储函数调用时传入的所有实参,尤其适用于处理 “参数数量不确定” 的场景(如不定参求和)。但随着 ES6 的普及,arguments逐渐被更灵活的剩余参数替代,需明确其特性、使用限制与过渡方案。本节将从arguments的基础特性入手,详解其使用方法与实战案例,同时对比 ES6 替代方案,帮助掌握函数参数的灵活处理技巧。

7.1 arguments 参数的基础特性

arguments并非普通变量,而是函数内部默认存在的 “类数组对象”,仅在非箭头函数中可用,核心特性围绕 “参数存储、类型本质、额外参数获取” 展开。

7.1.1 核心特性解析
特性类别具体说明示例验证
特殊对象属性是函数内部的局部变量,仅在函数体内生效,全局作用域中无法访问全局打印console.log(arguments) → 报错(未定义)
参数存储规则按函数调用时的实参顺序存储,索引从 0 开始(如第一个实参存于arguments[0]调用sum(10,20,30)arguments[0]=10arguments[1]=20
类数组(array-like)本质属于object类型,具备数组的 “索引访问” 和 “length 属性”,但无数组的内置方法(如pushforEachtypeof argumentsobjectarguments.forEachundefined
额外参数捕获无论函数是否定义形参,或实参数量超过形参数量,所有实参都会存入arguments函数function sum(a,b){}调用sum(10,20,30)arguments[2]=30(捕获额外实参)
7.1.2 关键注意事项
  1. 作用域限制:仅在非箭头函数中存在,箭头函数没有arguments对象(需用剩余参数替代);

  2. 动态关联:若函数定义了形参,

    arguments

    的索引值与形参值会 “动态同步”(修改形参值会影响

    arguments

    ,反之亦然),但在严格模式(

    'use strict'

    )下此关联会失效;

    // 非严格模式:形参与arguments动态同步
    function test(a) {a = 20;console.log(arguments[0]); // 输出20(形参修改影响arguments)arguments[0] = 30;console.log(a); // 输出30(arguments修改影响形参)
    }
    test(10);
    ​
    // 严格模式:关联失效
    function testStrict(a) {'use strict';a = 20;console.log(arguments[0]); // 输出10(形参修改不影响arguments)
    }
    testStrict(10);
  3. 长度属性(length):

    arguments.length

    表示函数调用时实际传入的实参数量,与函数定义的形参数量无关;

    function fn(a, b) {console.log(arguments.length); // 输出实参数量,而非形参数量
    }
    fn(10); // 实参1个 → 输出1
    fn(10, 20, 30); // 实参3个 → 输出3
7.2 函数中 arguments 变量的使用方法

arguments的核心价值是 “灵活处理不确定数量的参数”,需掌握其访问方式、遍历方法与使用场景。

7.2.1 基础使用:访问与遍历
  1. 索引访问:通过arguments[索引]获取单个实参,索引从 0 开始,上限为arguments.length - 1

    function showArgs() {console.log("第一个参数:", arguments[0]);console.log("第二个参数:", arguments[1]);console.log("参数总数:", arguments.length);
    }
    showArgs("a", 123, true); 
    // 输出:第一个参数:a → 第二个参数:123 → 参数总数:3
  2. 遍历参数:因arguments是类数组,无法直接使用forEach等数组方法,需通过for循环遍历(基于length属性);

    function logAllArgs() {// for循环遍历所有参数for (let i = 0; i < arguments.length; i++) {console.log(`第${i+1}个参数:`, arguments[i]);}
    }
    logAllArgs("apple", "banana", "orange");
    // 输出:第1个参数:apple → 第2个参数:banana → 第3个参数:orange
7.2.2 核心特点总结
  • 自动包含所有实参:无论函数是否定义形参(如function fn(){}),调用时传入的所有实参都会被arguments捕获;

  • 与形参独立:即使形参数量少于实参,额外的实参仍可通过arguments访问(如function fn(a){}调用fn(1,2)arguments[1]可获取 2);

  • 局部性:仅在函数内部可见,函数外部无法访问,避免全局变量污染。

7.3 arguments 的实战案例:不定参求和

arguments最典型的应用是 “处理参数数量不确定的场景”,以 “不定参求和” 为例,详解其实现逻辑与注意事项。

7.3.1 案例需求

定义一个函数sum,可接收任意数量的数字参数(如 1 个、2 个、5 个),返回所有参数的总和。

7.3.2 实现步骤
  1. 不定义具体形参:函数无需预先声明形参(或声明任意数量形参),通过arguments获取所有实参;

  2. 遍历 arguments 累加:用for循环遍历arguments,将每个参数转为数字(避免非数字类型影响结果)后累加;

  3. 返回累加结果:通过return将总和返回给外部。

7.3.3 完整代码
// 不定参求和函数:接收任意数量的数字参数,返回总和
function sum() {let total = 0; // 初始化总和为0// 遍历arguments,累加所有参数for (let i = 0; i < arguments.length; i++) {// 将参数转为数字,避免字符串拼接等异常const num = Number(arguments[i]);// 若转换后是有效数字,才累加(过滤NaN)if (!isNaN(num)) {total += num;}}return total; // 返回总和
}
​
// 测试用例
console.log(sum(10, 20)); // 2个参数 → 输出30
console.log(sum(5, 10, 15, 20)); // 4个参数 → 输出50
console.log(sum(2, 4, 6, 8, 10)); // 5个参数 → 输出30
console.log(sum(10, "20", 30)); // 含字符串参数 → 转为数字后累加,输出60
7.3.4 注意事项
  1. 类型转换arguments存储的是实参的原始类型(如字符串 “20”),需手动转为目标类型(如Number()转数字),避免逻辑错误(如字符串拼接而非加法);

  2. 数组方法限制:

    arguments

    无法直接使用

    forEach

    reduce

    等数组方法,若需使用,需先将其转为真正的数组(如

    const args = Array.from(arguments)

    );

    // 转为数组后使用reduce求和
    function sumWithReduce() {const args = Array.from(arguments); // 类数组转数组return args.reduce((total, curr) => {const num = Number(curr);return !isNaN(num) ? total + num : total;}, 0);
    }
  3. ES6 替代方案:ES6 引入的 “剩余参数(...args)” 可直接接收不定数量的参数并转为数组,语法更简洁,推荐优先使用(见 7.4)。

7.4 知识小结:arguments 的核心考点与 ES6 过渡
知识点核心内容考试重点 / 易混淆点难度系数
arguments 对象基础函数内部的类数组对象,存储所有实参;仅非箭头函数可用,全局不可访问arguments的类型(object而非array);与形参的动态关联(严格模式下失效)⭐⭐⭐
函数参数传递机制形参仅接收部分实参,arguments捕获所有实参;arguments.length表示实参数量形参数量与arguments.length无必然关联(实参可多于 / 少于形参);额外实参的获取方式⭐⭐
类数组特性具备索引访问和length属性,无数组内置方法(push/forEach等)类数组与真实数组的区别(typeof结果、方法可用性);类数组转数组的方法(Array.from()⭐⭐⭐⭐
不定参处理案例通过arguments实现不定参求和,需遍历累加并处理类型转换非数字参数的过滤(isNaN判断);arguments遍历与数组遍历的差异⭐⭐⭐
作用域预告arguments是函数局部变量,体现 “函数作用域” 与 “全局作用域” 的隔离箭头函数无arguments的原因;函数内外变量的访问权限差异⭐⭐⭐
ES6 替代方案(剩余参数)剩余参数...args接收不定参并转为数组,语法简洁,支持数组方法arguments与剩余参数的区别(类数组 vs 数组、兼容性);剩余参数的使用场景(优先于arguments⭐⭐⭐⭐
7.5 实战建议:arguments 与剩余参数的选择
  1. 兼容性场景:若需兼容 ES5 及以下环境(如 IE 浏览器),可使用arguments

  2. 现代开发场景:优先使用 ES6 剩余参数(

    ...args

    ),原因如下:

    • 语法更直观:function sum(...args) {}直接表明 “接收不定参”,可读性更高;

    • 天然是数组:args是真正的数组,可直接使用forEachreduce等方法,无需手动转换;

    • 箭头函数支持:箭头函数无arguments,但可使用剩余参数(如const sum = (...args) => args.reduce(...));

  3. 特殊需求:若需获取 “形参与arguments的动态关联”(非严格模式),可临时使用arguments,否则优先剩余参数。

8. JavaScript 作用域基础:概念、类型与 ES5 特性解析

作用域是 JavaScript 中变量访问规则的核心概念,决定了变量(或标识符)的有效访问范围。ES5 及之前的版本中,作用域的特性与现代 ES6 存在显著差异(如无块级作用域),理解这些基础规则是掌握变量管理的关键。本节将从作用域的基本概念入手,详解全局作用域、函数作用域的特性,以及 ES5 中 “无块级作用域” 的特殊表现。

8.1 作用域的基本概念与全局作用域

作用域的核心是 “变量可被访问的有效范围”,其中全局作用域是范围最广的一种,需明确其定义、访问规则与特殊现象。

8.1.1 作用域的定义与全局作用域
  • 核心定义:作用域(scope)指变量或标识符能够被访问的有效范围,超出该范围则无法引用。

  • 全局作用域:在

    <script>

    标签内直接定义的变量(未嵌套在任何函数或代码块中)属于全局作用域,具备以下特点:

    • 访问范围:在脚本的任何位置(包括函数内部、条件语句块、循环块等)均可访问;

    • 示例验证:

      // 全局变量:在全局作用域定义
      var message = "Hello World";
      ​
      // 在if语句块中访问全局变量
      if (true) {console.log(message); // 输出:Hello World(可访问)
      }
      ​
      // 在函数内部访问全局变量
      function foo() {console.log(message); // 输出:Hello World(可访问)
      }
      foo();
8.1.2 作用域的 “变量提升” 现象

ES5 中存在 “变量提升” 机制,导致 “变量在定义前可被访问” 的特殊表现:

  • 现象:在变量定义语句之前访问变量,不会报错,而是返回

    undefined

    (而非未定义错误);

    console.log(message); // 输出:undefined(未报错)
    var message = "Hello World"; // 变量定义
  • 当前理解要点:只要变量在脚本中被定义(无论定义位置),其作用域会覆盖定义后的所有代码(包括函数、条件块等);

  • 术语与背景:作用域对应的英文为 “scope”;ES5 及之前的版本中,变量提升是作用域的重要特性,后续课程会深入解析其原理。

8.2 ES5 之前的 “无块级作用域” 特性

ES5 及之前的版本中,使用var定义的变量不具备 “块级作用域”(即代码块{}不会形成独立作用域),这是与现代 ES6 差异的核心点。

8.2.1 块级作用域的缺失:var与代码块的关系
  • 核心表现:用

    var

    定义的变量,其作用域不受代码块

    {}

    限制(无论if、for、while等代码块),在块外仍可访问;

    // if代码块内用var定义变量
    if (true) {var blockVar = "我在if块内定义";
    }
    console.log(blockVar); // 输出:我在if块内定义(块外可访问)
    ​
    // for循环块内用var定义变量
    for (var i = 0; i < 3; i++) {}
    console.log(i); // 输出:3(循环块外可访问,值为循环结束后的值)
  • 历史背景:ES5 及之前只有var一种变量声明方式,而var不支持块级作用域,因此可认为 “ES5 之前没有块级作用域的概念”。

8.2.2 控制语句中的作用域表现

所有控制语句(ifforwhile等)的代码块均不会形成独立作用域,变量作用域穿透代码块:

  • for 循环示例:循环变量i在循环结束后仍可访问,且值为循环终止时的结果;

  • if 语句示例:条件块内定义的变量,在条件外仍可访问(如上述blockVar案例);

  • 结论:ES5 中,代码块{}仅用于逻辑分组,不影响变量的作用域范围。

8.3 函数作用域:ES5 中唯一的 “局部作用域”

在 ES5 及之前,函数是唯一能形成 “局部作用域” 的结构 —— 函数内部定义的变量仅在函数内可访问,外部无法引用,这是与代码块的核心区别。

8.3.1 函数作用域的基本特性
  • 核心表现:函数内部用

    var

    定义的变量属于 “函数作用域”,仅在函数体内有效,函数外部无法访问;

    function test() {var innerVar = "函数内部变量";console.log(innerVar); // 输出:函数内部变量(函数内可访问)
    }
    test();
    console.log(innerVar); // 报错:innerVar is not defined(外部不可访问)
8.3.2 嵌套函数的作用域规则

当函数嵌套时(内部函数定义在外部函数内),作用域遵循 “内层可访问外层,外层不可访问内层” 的规则:

  • 内层函数访问外层变量:内部函数可访问外部函数的变量(闭包的基础);

  • 外层无法访问内层变量:外部函数(或全局)无法访问内部函数的变量;

    function outer() {var outerVar = "外层变量";
    ​// 嵌套的内部函数function inner() {var innerVar = "内层变量";console.log(outerVar); // 输出:外层变量(内层可访问外层)}
    ​inner();console.log(innerVar); // 报错:innerVar is not defined(外层不可访问内层)
    }
    outer();
8.4 知识小结:ES5 作用域的核心考点
知识点核心内容考试重点 / 易混淆点难度系数
作用域基本概念变量的有效访问范围(scope);全局变量在整个脚本范围内可访问全局作用域与函数作用域的边界;变量 “可访问” 与 “已定义” 的区别(如变量提升导致的 undefined)⭐⭐
ES5 的无块级作用域var定义的变量不受代码块{}限制,if/for块内变量在块外可访问for 循环中变量i的 “泄漏” 问题(循环结束后仍可访问);var与后续let的块级作用域差异(预告)⭐⭐⭐
函数作用域函数内部形成独立作用域,变量仅内部可访问;嵌套函数可访问外层变量函数内外变量的访问权限(外层不可访问内层);函数作用域与全局作用域的嵌套关系⭐⭐
变量提升现象变量定义前访问返回undefined,而非报错变量 “声明提升” 与 “赋值不提升” 的区别(如console.log(a); var a=1;a声明被提升,赋值未提升)⭐⭐⭐⭐
ES6 块级作用域(预告)let/const引入块级作用域,解决var的作用域穿透问题varlet在 for 循环中的表现对比(如let定义的i不会泄漏到循环外)⭐⭐⭐
8.5 核心结论
  • 作用域的本质是 “变量的有效访问范围”,决定了变量在何处可被引用;

  • ES5 及之前:

    • 只有 “全局作用域” 和 “函数作用域”,无块级作用域;

    • var定义的变量不受代码块限制,但受函数边界限制;

    • 函数是唯一能创建局部作用域的结构,嵌套函数可访问外层变量。

  • 理解这些特性是后续学习 ES6 块级作用域、闭包等概念的基础。

9. JavaScript 变量类型与访问规则:全局、局部变量及作用域链

变量是 JavaScript 中数据存储的基本单元,其可访问范围与查找顺序由作用域规则决定。本节将系统梳理全局变量、局部变量、外部变量的核心概念,详解变量访问时的 “作用域链” 规则,帮助建立变量管理的清晰认知。

9.1 全局变量、局部变量与外部变量的概念

根据变量的定义位置与作用域范围,可将变量划分为三类:全局变量、局部变量、外部变量,三者的核心特征与访问范围存在显著差异。

9.1.1 全局变量(Global Variable)
  • 定义位置:在<script>标签最顶层(所有函数外部)定义的变量;

  • 核心特征:

    • 访问范围:在代码的任何位置均可访问,包括函数内部、嵌套函数、条件语句块、循环块等;

    • 示例:

      // 全局变量:定义在所有函数外部
      var message = "hello world";
      ​
      function sayHello() {console.log(message); // 可访问全局变量 → 输出:hello world
      }
      ​
      function outer() {function inner() {console.log(message); // 嵌套函数中仍可访问 → 输出:hello world}inner();
      }
      outer();
    • 特殊机制:全局变量默认会被添加到window对象(如window.message可获取全局变量值),具体原理后续课程详解;

    • 注意事项:若使用var声明,在变量定义前访问会触发 “变量提升”(返回undefined);若使用let声明,提前访问会直接报错(块级作用域特性)。

9.1.2 局部变量(Local Variable)
  • 定义位置:在函数内部定义的变量;

  • 核心特征:

    • 作用域限制:仅能在定义它的函数内部被访问,函数外部(包括全局或其他函数)无法引用;

    • 示例:

      function sayHello() {// 局部变量:仅在sayHello函数内有效var nickname = "小明";console.log(nickname); // 输出:小明(函数内可访问)
      }
      sayHello();
      console.log(nickname); // 报错:nickname is not defined(外部不可访问)
9.1.3 外部变量(Outer Variable)
  • 定义:函数内部访问的、非自身定义的变量(即不属于当前函数作用域的变量);

  • 判定标准:

    • 若函数访问的变量是 “外层函数定义的变量”(如嵌套函数访问外层函数的变量),属于外部变量;

    • 若函数访问的变量是 “全局变量”(函数外部定义的变量),也属于外部变量;

  • 示例:

    // 全局变量(对所有函数而言,若未重新定义则为外部变量)
    var globalVar = "全局变量";
    ​
    function outer() {// 外层函数变量(对inner而言是外部变量)var outerVar = "外层变量";
    ​function inner() {// 访问外部变量:outerVar(外层函数变量)和globalVar(全局变量)console.log(outerVar); // 输出:外层变量console.log(globalVar); // 输出:全局变量}inner();
    }
    outer();
9.1.4 三类变量的对比总结
变量类型定义位置访问范围英文术语
全局变量<script>顶层 / 函数外部整个程序(所有函数、代码块内)Global Variable
局部变量函数内部仅限定义它的函数内部Local Variable
外部变量非当前函数作用域(外层函数或全局)被当前函数访问(作为外部依赖)Outer Variable
9.2 变量的访问顺序:作用域链规则

当函数访问变量时,并非随机查找,而是遵循 “作用域链” 规则 —— 从当前作用域开始,逐层向上查找,直至找到变量或确定不存在。

9.2.1 基本访问规则

变量查找顺序为:

  1. 优先查找当前函数作用域:先检查当前函数内部是否定义了该变量,若有则直接访问;

  2. 向上层作用域查找:若当前函数未定义,向上查找外层函数(若存在嵌套)的作用域;

  3. 查找全局作用域:若外层函数也未定义,继续查找全局作用域(<script>顶层定义的变量);

  4. 检查 window 对象:若全局作用域仍未定义,检查window对象是否有该属性(全局变量默认挂载到window);

  5. 未找到则报错:若所有层级均未找到,触发ReferenceError: 变量 is not defined

核心原则:“就近原则”—— 多层作用域存在同名变量时,优先访问 “最近作用域” 的变量。

9.2.2 例题分析:变量访问顺序的具体表现
例题 1:访问当前函数作用域的变量
function foo() {var message = "当前函数的局部变量";console.log(message); // 优先访问当前函数的变量 → 输出:当前函数的局部变量
}
foo();

结论:当前函数定义了变量时,直接访问该局部变量。

例题 2:访问上层作用域的变量
function outer() {var message = "外层函数的变量";function inner() {// inner内部未定义message,向上查找外层函数console.log(message); // 输出:外层函数的变量}inner();
}
outer();

变体:若外层变量未初始化(仅声明),访问结果为undefined

function outer() {var message; // 仅声明,未赋值function inner() {console.log(message); // 输出:undefined(找到变量但未初始化)}inner();
}
outer();
例题 3:访问全局作用域的变量
// 全局变量
var message = "全局变量";
​
function outer() {function inner() {// 自身和外层函数均未定义message,查找全局console.log(message); // 输出:全局变量}inner();
}
outer();
例题 4:访问 window 对象的变量(全局变量的特殊挂载)
// 全局变量默认挂载到window
var message = "全局变量";
​
function foo() {console.log(window.message); // 输出:全局变量(通过window访问全局变量)
}
foo();

注意:若变量未定义,window.变量会返回undefined(而非报错):

function foo() {console.log(window.undefinedVar); // 输出:undefined(window无此属性)console.log(undefinedVar); // 报错:ReferenceError(未找到变量)
}
foo();
9.3 总结:变量访问的核心逻辑
  • 变量按 “全局变量、局部变量、外部变量” 分类,核心区别在于定义位置与访问范围;

  • 变量访问遵循 “作用域链” 规则:从当前函数作用域开始,逐层向上查找,直至window对象,未找到则报错;

  • “就近原则” 是变量访问的关键:同名变量时,优先选择最近作用域的定义。

这些规则是理解 JavaScript 变量管理的基础,直接影响后续闭包、模块化等高级概念的学习,需重点掌握。

10. JavaScript 作用域与函数表达式:概念及差异解析

作用域决定了变量的访问范围,而函数作为 JavaScript 中的特殊值,存在函数声明与函数表达式两种定义方式,二者在创建时机、调用规则上存在显著差异。本节将系统梳理作用域中的变量分类、访问规则,详解函数表达式的特性及其与函数声明的核心区别,构建对变量与函数定义的完整认知。

10.1 作用域与变量类型

作用域是标识符(变量、函数名等)的有效访问范围,ES5 及之前虽无块级作用域,但函数可形成独立作用域,变量按作用域范围可分为局部变量、外部变量与全局变量。

10.1.1 作用域的核心定义
  • 基本概念:作用域指变量或函数名能够被访问的有效范围,超出该范围则无法引用;

  • ES5 特性:不存在块级作用域(代码块{}不限制变量访问),但函数可定义独立作用域(函数内部形成局部范围)。

10.1.2 变量类型及特征
  1. 局部变量

    • 定义位置:函数内部;

    • 访问范围:仅限定义它的函数内部,外部无法访问;

    • 示例:

      function foo() {var localVar = "局部变量"; // 局部变量console.log(localVar); // 输出:局部变量(函数内可访问)
      }
      foo();
      console.log(localVar); // 报错:localVar is not defined(外部不可访问)
  2. 外部变量

    • 定义:函数内部访问的、非自身定义的变量(即来自函数外部的变量);

    • 范围:包括外层函数的变量或全局变量;

    • 示例:

      var globalVar = "全局变量"; // 全局变量(对所有函数是外部变量)
      ​
      function outer() {var outerVar = "外层变量"; // 对inner是外部变量function inner() {console.log(outerVar); // 访问外层函数的外部变量 → 输出:外层变量console.log(globalVar); // 访问全局的外部变量 → 输出:全局变量}inner();
      }
      outer();
  3. 全局变量

    • 定义位置:<script>标签内(所有函数外部);

    • 访问范围:在任何函数、代码块中均可访问;

    • 特殊机制:通过var声明的全局变量会成为window对象的属性(如window.globalVar可访问);

    • 示例:

      var globalVar = "全局变量";
      function test() {console.log(globalVar); // 函数内可访问 → 输出:全局变量
      }
      test();
      console.log(window.globalVar); // 输出:全局变量(挂载到window)
10.1.3 变量访问顺序

遵循 “就近原则”:

  1. 优先访问当前函数内部的局部变量;

  2. 未找到则向上层作用域(外层函数)查找外部变量;

  3. 仍未找到则访问全局变量;

  4. 全局未定义则报错(ReferenceError)。

10.2 函数表达式:定义与特性

函数在 JavaScript 中是特殊的 “值”(类型为function,本质是对象),除函数声明外,还可通过 “函数表达式” 定义,二者在语法与执行机制上存在差异。

10.2.1 函数表达式的定义
  • 语法:将函数赋值给变量,即 “变量 = function (参数){...}”;

  • 匿名特性:函数表达式可省略函数名(匿名函数),通过变量名调用;

  • 示例:

    // 函数表达式:将匿名函数赋值给变量foo
    var foo = function() {console.log("函数表达式");
    };
    ​
    // 通过变量名调用
    foo(); // 输出:函数表达式
10.2.2 函数声明与函数表达式的区别
对比维度函数声明(Function Declaration)函数表达式(Function Expression)
语法形式独立语句:function 函数名(参数){...}表达式中定义:变量 = function(参数){...}
创建时机JavaScript 预处理阶段(脚本运行前)创建代码执行到定义行时才创建
调用时机可在定义前调用(预处理机制)必须在定义后调用(否则变量为undefined,调用报错)
命名要求必须有函数名(通过函数名调用)可省略函数名(通过变量名调用)

  • 示例:创建与调用时机差异

    // 函数声明:可在定义前调用
    testDeclaration(); // 输出:函数声明(预处理时已创建)
    function testDeclaration() {console.log("函数声明");
    }
    ​
    // 函数表达式:定义前调用报错
    testExpression(); // 报错:testExpression is not a function(未执行到定义行,变量为undefined)
    var testExpression = function() {console.log("函数表达式");
    };
10.2.3 开发实践建议
  • 优先使用函数声明:因其支持提前调用,灵活性更高;

  • 函数表达式用于特殊场景:如作为参数传递(回调函数)、创建匿名函数等;

  • 注意:函数表达式赋值后,变量存储的是函数引用,可像普通值一样传递。

10.3 知识小结:核心考点与难度梳理
知识点核心内容考试重点 / 易混淆点难度系数
作用域与变量类型作用域是变量的有效范围;变量分局部(函数内)、外部(函数外)、全局(script 顶层)变量访问的 “就近原则”;全局变量挂载到window的特性⭐⭐
函数表达式通过 “变量 = function (){...}” 定义,属于表达式语法;可匿名与函数声明的语法差异;调用时机限制(定义后才能调用)⭐⭐⭐
函数的本质函数是特殊的值(类型为function),本质是对象函数作为 “头等公民” 的特性(可赋值给变量、作为参数传递)⭐⭐
声明与表达式的差异函数声明预处理时创建,可提前调用;表达式执行到定义行才创建,不可提前调用二者创建时机的底层机制;提前调用表达式导致的报错原因(变量暂为undefined⭐⭐⭐⭐
开发实践优先用函数声明,特殊场景用表达式;匿名函数是表达式的常见形式函数表达式作为回调函数的应用(如setTimeout(函数表达式, 1000)⭐⭐
10.4 核心结论
  • 作用域决定变量访问范围,变量按作用域分为局部、外部、全局,访问遵循 “就近原则”;

  • 函数表达式是定义函数的重要方式,与函数声明的核心差异在于创建时机与调用限制;

  • 理解二者特性有助于合理选择函数定义方式,避免因调用时机错误导致的逻辑问题。

11. JavaScript 中的头等函数与函数式编程

在 JavaScript 中,函数被视为 “头等公民”(First-Class Function),这意味着函数可像普通值一样被灵活操作(如作为参数、返回值、存储在变量或数据结构中)。这种特性是函数式编程的基础,使 JavaScript 具备高度灵活性。本节将详解头等函数的核心特性、函数式编程的概念及实践案例,理解这一特性对掌握 JavaScript 高级用法至关重要。

11.1 函数的头等公民特性

“头等函数” 指函数在编程语言中拥有与其他数据类型(如数字、字符串)同等的地位,可被任意操作。JavaScript 完全支持这一特性,具体表现为以下核心能力。

11.1.1 函数的表达式写法:赋值与传递

函数可被赋值给变量,且变量间可传递函数引用,这是头等函数最直接的体现。

  • 基础示例:

    // 函数表达式:将函数赋值给变量foo1
    const foo1 = function() {console.log("执行函数");
    };
    foo1(); // 通过变量名调用 → 输出:执行函数
    ​
    // 函数在变量间传递(赋值引用)
    const foo2 = foo1; // foo2与foo1指向同一个函数
    foo2(); // 调用 → 输出:执行函数(与foo1效果一致)
  • 本质:函数是特殊的 “值”,变量存储的是函数的引用,而非函数本身,因此可像普通值一样传递。

11.1.2 函数作为参数、返回值与存储载体

头等函数的核心特性还包括 “作为参数传递”“作为返回值”“存储在数据结构中”,这些能力是函数式编程的基础。

11.1.2.1 函数作为参数传递

函数可作为实参传入其他函数,被调用函数可通过形参执行传入的函数(即 “回调函数” 模式)。

  • 示例:

    // 定义一个接收函数作为参数的函数bar
    function bar(fn) {console.log("执行传入的函数:");fn(); // 执行传入的函数
    }
    ​
    // 定义要传入的函数foo
    const foo = function() {console.log("我是被传入的函数");
    };
    ​
    // 调用bar,传入foo作为参数
    bar(foo); 
    // 输出:执行传入的函数:→ 我是被传入的函数
11.1.2.2 函数作为返回值

函数可作为另一个函数的返回值,外部通过调用返回的函数实现逻辑延迟执行(如柯里化)。

  • 示例:

    // 函数createHello返回一个新函数
    function createHello(name) {// 返回一个匿名函数,引用外部变量namereturn function() {console.log(`hi, ${name}`);};
    }
    ​
    // 调用createHello,获取返回的函数
    const sayHiToCopy = createHello("copy");
    sayHiToCopy(); // 执行返回的函数 → 输出:hi, copy
  • 扩展:这种 “返回函数” 的模式称为柯里化(Currying),可实现参数复用与逻辑拆分,后续课程会深入讲解。

11.1.2.3 函数存储在数据结构中

函数可像普通值一样存储在对象、数组等数据结构中,通过访问数据结构调用函数。

  • 对象中存储函数

    const person = {name: "小明",// 函数作为对象的方法存储eating: function() {console.log(`${this.name}在吃饭`);},running: function() {console.log(`${this.name}在跑步`);}
    };
    // 调用对象中的函数
    person.eating(); // 输出:小明在吃饭
    person.running(); // 输出:小明在跑步
  • 数组中存储函数

    // 数组中存储多个函数
    const actionFunctions = [function() { console.log("动作1:跳"); },function() { console.log("动作2:跑"); },function() { console.log("动作3:走"); }
    ];
    // 调用数组中的函数(通过索引访问)
    actionFunctions[0](); // 输出:动作1:跳
    actionFunctions[2](); // 输出:动作3:走
11.2 函数式编程:理念与语言对比

函数式编程是一种以 “函数为核心” 的编程范式,JavaScript 因支持头等函数而天然适配这种范式。

11.2.1 函数式编程的核心特征

函数式编程的核心依赖于头等函数的特性,具体表现为:

  • 函数可被任意传递、返回或存储,作为逻辑的基本单元;

  • 支持高阶函数(接收或返回函数的函数);

  • 鼓励使用匿名函数简化逻辑;

  • 强调 “无副作用”(函数执行不修改外部状态)与 “纯函数”(输入相同则输出必相同)。

11.2.2 不同语言对函数式编程的支持对比

并非所有语言都原生支持函数式编程,对比不同语言的特性可更清晰理解 JavaScript 的优势:

语言对函数式编程的支持情况特点与限制
JavaScript原生支持头等函数,完全适配函数式编程灵活度高,函数可作为参数、返回值等,是语言核心特性之一
Java早期版本不支持(需通过内部类模拟),Java 8 引入 Lambda 表达式后有限支持语法较繁琐,函数式编程并非核心设计,更多作为补充特性
Swift原生支持函数式编程,将其作为现代语言特性之一设计时融入函数式思想,支持高阶函数、闭包等,灵活性接近 JavaScript
Lisp函数式编程思想的起源语言(1958 年诞生)开创性提出函数作为头等公民的理念,影响后续所有支持函数式编程的语言
11.2.3 函数式编程思想的起源与影响

函数式编程思想源自 1958 年的 Lisp 语言,其核心理念是 “将计算视为函数的组合”。尽管 Lisp 较为古老,但其提出的 “函数作为头等公民”“递归” 等理念深刻影响了现代编程语言(包括 JavaScript、Swift、Python 等)。

在 JavaScript 中,函数式编程思想的应用极为广泛,例如:

  • 数组方法(mapfilterreduce)均基于函数作为参数的模式;

  • 异步编程中的回调函数、Promise、async/await,本质依赖函数作为返回值或参数的特性;

  • 状态管理(如 Redux)的设计理念也借鉴了函数式编程的 “纯函数” 思想。

11.3 知识小结:头等函数与函数式编程的核心考点
知识点核心内容考试重点 / 易混淆点难度系数
头等函数的特性函数可作为参数、返回值、赋值给变量、存储在数据结构中函数作为 “值” 的本质(变量存储引用);与非头等函数语言(如早期 Java)的区别⭐⭐⭐
函数表达式与传递函数表达式是头等函数的体现(赋值给变量);函数可在变量间传递函数引用传递的特性(赋值后变量指向同一函数);函数表达式与函数声明的调用差异⭐⭐
函数作为参数 / 返回值函数作为参数实现回调;作为返回值实现延迟执行(如柯里化)回调函数的执行时机;返回函数对外部变量的引用(闭包基础)⭐⭐⭐
函数式编程的支持JavaScript 原生支持,依赖头等函数特性;不同语言的支持对比(Java/Swift/Lisp)Java 与 JavaScript 在函数式编程支持上的差异;Lisp 作为思想起源的地位⭐⭐
函数式编程的影响影响数组方法、异步编程、状态管理等众多领域函数式编程与命令式编程的区别(前者强调函数组合,后者强调步骤执行)⭐⭐⭐⭐
11.4 核心结论
  • JavaScript 中的函数是 “头等公民”,可作为参数、返回值、变量值或数据结构元素,具备高度灵活性;

  • 这种特性使 JavaScript 天然支持函数式编程,是其区别于传统面向对象语言的重要优势;

  • 理解头等函数的特性是掌握回调函数、柯里化、数组高阶方法等高级用法的基础,需重点掌握函数作为参数与返回值的实践场景。

12. JavaScript 函数式编程核心:头等函数与高阶函数应用

JavaScript 因支持 “头等函数” 特性,衍生出回调函数、高阶函数、匿名函数等重要概念,这些是函数式编程的核心组成部分,尤其在异步编程、逻辑抽象中发挥关键作用。本节将从头等函数的基础特性入手,详解回调函数的异步应用、高阶函数的判定与使用,以及匿名函数的简化逻辑,构建函数式编程的核心知识体系。

12.1 头等函数的特性与函数式编程基础

头等函数(First-Class Function)是 JavaScript 函数式编程的根基,指函数具备与普通值同等的地位,可被灵活操作。

12.1.1 头等函数的核心特性

函数作为 “头等公民”,需满足以下关键特性:

  • 作为参数传递:函数可作为实参传入其他函数(如回调函数);

  • 作为返回值:函数可被另一个函数返回(如柯里化场景);

  • 赋值与存储:可赋值给变量,或存储在数组、对象等数据结构中;

  • 支持匿名函数:允许定义无名称的函数,简化临时逻辑。

这些特性使 JavaScript 天然支持函数式编程范式 —— 以函数为核心构建逻辑,强调函数的组合与复用。

12.1.2 函数式编程的核心场景

函数式编程依赖头等函数特性,典型应用包括:

  • 异步操作处理(通过回调函数获取异步结果);

  • 数据处理(通过高阶函数如mapfilter抽象逻辑);

  • 逻辑复用(通过函数返回函数实现参数固化)。

12.2 回调函数:异步逻辑的核心机制

回调函数(Callback Function)是头等函数特性的典型应用,指 “被作为参数传递给另一个函数,并在特定时刻被调用的函数”,尤其适用于处理异步操作。

12.2.1 回调函数的定义与核心特征
  • 核心定义:通过变量引用传递给其他函数,在非定义位置被调用的函数;

  • 关键作用:解决异步操作的 “结果获取” 问题(如网络请求、定时器等耗时操作);

  • 核心特征:

    • 作为参数传递给高阶函数;

    • 在特定时机(如异步操作完成后)被触发执行;

    • 无需主动调用,由接收它的函数负责执行。

12.2.2 回调函数的实践案例
案例 1:模拟网络请求的回调处理

网络请求是典型的异步场景,无法通过return直接获取结果,需通过回调函数传递:

// 模拟网络请求函数(高阶函数,接收回调函数)
function request(url, callback) {// 模拟请求延迟(异步操作)setTimeout(() => {const result = ["JavaScript", "函数式编程", "回调函数"]; // 模拟请求结果callback(result); // 操作完成后调用回调,传递结果}, 1000);
}
​
// 定义处理结果的回调函数
function handleResult(res) {console.log("处理请求结果:", res);
}
​
// 调用请求函数,传入回调
request("https://example.com/data", handleResult); 
// 1秒后输出:处理请求结果:["JavaScript", "函数式编程", "回调函数"]
案例 2:回调函数的正确传递方式

传递回调函数时需注意 “引用传递” 与 “立即执行” 的区别:

  • 错误写法request(url, handleResult())—— 加括号会立即执行函数,传递的是返回值(而非函数引用);

  • 正确写法request(url, handleResult)—— 传递函数名(引用),由request在合适时机调用。

案例 3:匿名函数简化回调逻辑

对于仅使用一次的回调函数,可直接定义为匿名函数,简化代码:

// 匿名函数作为回调,无需单独定义handleResult
request("https://example.com/data", function(res) {console.log("匿名函数处理结果:", res);
});
// 效果与案例1一致,代码更简洁
12.3 高阶函数:接收或返回函数的函数

高阶函数(Higher-Order Function)是函数式编程的重要工具,指 “接收函数作为参数” 或 “返回函数” 的函数,是回调函数得以应用的基础。

12.3.1 高阶函数的判定标准

满足以下任一条件即为高阶函数:

  1. 接收函数作为参数(如request函数接收回调函数);

  2. 返回一个函数(如柯里化函数返回新函数)。

12.3.2 典型示例
// 示例1:接收函数作为参数(高阶函数)
function higherOrder1(fn) {console.log("执行传入的函数:");fn(); // 调用传入的函数
}
// 调用:传入匿名函数作为参数
higherOrder1(function() {console.log("我是被传入的函数");
});
​
// 示例2:返回一个函数(高阶函数)
function higherOrder2(msg) {// 返回一个新函数,引用外部变量msgreturn function() {console.log("返回的函数执行:", msg);};
}
// 调用:获取返回的函数并执行
const returnedFn = higherOrder2("Hello");
returnedFn(); // 输出:返回的函数执行:Hello
12.3.3 内置高阶函数(预告)

JavaScript 数组方法(如mapfilterreduce)均为高阶函数,后续课程会详解,例如:

// map是高阶函数,接收函数作为参数
const numbers = [1, 2, 3];
const doubled = numbers.map(function(n) { return n * 2; });
console.log(doubled); // 输出:[2,4,6]
12.4 匿名函数:简化回调的临时函数

匿名函数是 “无名称的函数表达式”,常与高阶函数、回调场景配合使用,简化代码结构。

12.4.1 匿名函数的定义与特点
  • 定义:通过function()语法定义,无函数名;

  • 使用场景:

    • 作为回调函数直接传递(无需重复使用);

    • 临时逻辑处理(如一次性操作);

  • 优势:减少命名冗余,使代码更紧凑;

  • 局限:无法在定义外通过名称调用,不适合复用逻辑。

12.4.2 与函数声明的对比
类型语法形式适用场景特点
匿名函数function() {...}临时回调、一次性逻辑简洁,无名称,不可复用
函数声明function 名称() {...}需多次调用、复用的逻辑可通过名称调用,支持提升
12.5 知识小结:核心考点与难度梳理
知识点核心内容考试重点 / 易混淆点难度系数
头等函数函数可作为参数、返回值或赋值给变量,支持函数式编程区分 “函数引用传递”(foo(bar))与 “函数立即执行”(foo(bar())⭐⭐
回调函数作为参数传递,在非定义位置被调用,用于异步操作异步场景中 “无法通过 return 获取结果” 的原因;回调函数的执行时机⭐⭐⭐
高阶函数接收函数作为参数或返回函数(如requestmap识别高阶函数的判定标准;与普通函数的区别⭐⭐
匿名函数无名称的函数表达式,常用于回调场景匿名函数与函数声明的适用场景;匿名函数无法通过名称复用的局限⭐⭐
异步请求处理通过回调函数获取异步操作结果(如模拟网络请求案例)理解异步执行的时序(回调函数后于主程序执行);与同步执行的区别⭐⭐⭐⭐
12.6 核心结论
  • 头等函数是 JavaScript 函数式编程的基础,使函数可作为参数、返回值等灵活操作;

  • 回调函数是异步编程的核心机制,通过 “延迟调用” 解决异步结果获取问题;

  • 高阶函数(接收或返回函数)是函数式编程的重要工具,支撑回调函数与逻辑抽象;

  • 匿名函数简化了临时逻辑(如回调)的代码结构,是开发中的常用写法。

掌握这些概念是理解 JavaScript 异步编程、数组高阶方法等高级内容的关键。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/95114.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/95114.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/95114.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenCV 轮廓分析实战:从检测到形状匹配的完整指南

轮廓&#xff08;Contour&#xff09;是图像中连续且具有相同灰度值的像素集合&#xff0c;是描述目标形状、位置和结构的核心特征。在计算机视觉中&#xff0c;轮廓分析广泛应用于目标定位、形状识别、尺寸测量等场景&#xff08;如工业零件检测、手写数字识别&#xff09;。本…

2025最新uni-app横屏适配方案:微信小程序全平台兼容实战

以下为uni-app实现微信小程序横屏适配技术方案&#xff0c;包含核心原理、配置方法、代码示例和注意事项&#xff1a;一、横屏适配原理 微信小程序默认采用竖屏模式&#xff0c;横屏适配需通过以下机制实现&#xff1a; 全局配置&#xff1a;在app.json中声明支持横屏页面级配置…

深入解析Nginx常见模块1

在Web服务器和反向代理服务器领域,Nginx凭借其高性能、稳定性和丰富的功能获得了广泛的应用。本文将介绍一些Nginx中常见的模块,帮助你更好地理解和使用它们。 Nginx模块简介 Nginx的模块系统是其强大功能的核心所在,它允许用户根据需要灵活配置服务器的行为。Nginx的模块大…

浅谈new与::operator new

目录 前言 1.为什么C要引入new/delete&#xff1f; 2.operator new与operator delete函数 它们的实际作用 Placement New&#xff08;定位new表达式&#xff09; 总结 前言 在写上一篇博客“vector的模拟实现”时&#xff0c;我一直很好奇vector的private成员为什么要用三个封…

Java中Integer转String

在 Java 中&#xff0c;将 Integer 转换为 String 有多种方法&#xff0c;以下是常见的几种方式&#xff1a;1. 使用 Integer.toString() 方法javaInteger num 123; String str Integer.toString(num); // 直接调用 Integer 的静态方法2. 使用 String.valueOf()javaInteger n…

智能装备如何与软件结合?

一、什么是智能装备&#xff1f; 智能装备是具备“感知-决策-执行-自适应”闭环能力的智能化系统&#xff0c;本质是“传统物理装备”与“数字智能”的深度融合。它不仅能完成预设动作&#xff08;如传统机械臂焊接&#xff09;&#xff0c;还能通过传感器“观察”环境、用算法…

react性能优化有哪些

React 性能优化的手段比较多&#xff0c;既有代码层面的&#xff0c;也有构建层面的&#xff0c;还涉及到运行时调优。我帮你系统性梳理一份&#xff1a;&#x1f539; 一、渲染性能优化1. 减少不必要的渲染React.memo&#xff1a;对函数组件做浅比较&#xff0c;避免相同 prop…

腾讯云OpenCloudOS 9系统部署OpenTenBase数据库详细教程

OpenTenBase简介OpenTenBase是一个关系型数据库集群平台&#xff0c;提供写入可靠性和多节点数据同步功能。可以在一台或多台主机上配置OpenTenBase&#xff0c;并将数据存储在多个物理主机上。OpenTenBase架构组件&#xff1a;Coordinator Node (CN)&#xff1a;应用程序访问入…

【计算机视觉】Pixel逐像素分类Mask掩码分类理解摘要

目标检测和实例分割是计算机视觉的基本任务。目标检测的传统方法中通常利用边界框技术进行对象定位&#xff0c;然后利用逐像素分类为这些本地化实例分配类。但是当处理同一类的重叠对象时&#xff0c;或者在每个图像的对象数量不同的情况下&#xff0c;这些方法通常会出现问题…

C++之stack类的代码及其逻辑详解

1. stack介绍及使用方法stack是一种后进先出的数据结构&#xff0c;所以在C的STL库中也同样遵循了这一点&#xff0c;我们在使用的时候不支持随机访问或迭代器遍历。注意事项调用 top() 或 pop() 前需确保栈非空&#xff0c;否则可能引发未定义行为。stack 没有 clear() 函数&a…

Spring Cache实现简化缓存功能开发

一. 介绍Spring Cache 是 Spring 框架提供的缓存抽象层&#xff0c;它简化了在应用中添加缓存功能的开发工作。通过 Spring Cache&#xff0c;开发者无需关注具体缓存实现的细节&#xff0c;只需通过注解就能快速实现方法级别的缓存管理。核心特点1. 与具体缓存实现解耦&#x…

Lombok(简化Java当中的开发)

Lombok概述 以前的Java项目中,充斥着太多不友好的代码:POJO的getter/setter/toString/构造方法;打印日志;I/O流的关闭操作等等,这些代码既没有技术含量,又影响着代码的美观,Lombok应运而生。 LomBok可以通过注解,帮助开发人员消除JAVA中尤其是POJO类中的冗长代码。 使…

【DeepSeek】公司内网部署离线deepseek+docker+ragflow本地模型实战

企业内部可能有些数据比较敏感&#xff0c;不能连接互联网。本次实验操作是将deepseek完全离线后迁移至内网使用&#xff0c;实验基于Windows server 2022 datacenter系统安装deepseek、docker、ragflow。 目录使用VMware新建WIN2022虚拟机一、安装DeepSeek模型二.安装Docker使…

【软考架构】面向服务的体系结构(SOA)深度解析

面向服务的体系结构&#xff08;SOA&#xff09;深度解析 面向服务的体系结构&#xff08;Service-Oriented Architecture, SOA&#xff09;是一种以服务为核心的软件架构范式&#xff0c;通过标准化接口实现异构系统间的高效集成与协作。以下从概念定义、发展脉络、技术演进、…

centos7中MySQL 5.7.32 到 5.7.44 升级指南:基于官方二进制包的原地替换式升级

目录前言1. 升级概述1.1 升级背景1.2 升级目的1.3 升级方法概述1.4 升级策略与注意事项2. 升级准备2.1 备份工作2.2 下载目标版本2.3 停止 MySQL 服务3. 替换二进制文件3.1 解压官方二进制包3.2 替换核心二进制文件3.3 更新共享库4. 执行升级并验证4.1 启动 MySQL 服务4.2 监控…

数学七夕花礼(MATLAB版)

前言参考的视频在抖音&#xff0c;电脑版的抖音一直登录不了&#xff0c;用手机分享的链接如下所示。4.35 Iv.FH yTl:/ 04/04 复制打开抖音&#x1f440;数学送的七夕花礼&#xff0c;记得查收噢.# 七夕花礼请查收 ... https://v.douyin.com/H-YpOJCyQyg/rho4sin(8theta)公式&a…

LeetCode - 21. 合并两个有序链表

题目 21. 合并两个有序链表 思路 我会采用双指针的方法&#xff0c;同时遍历两个链表&#xff0c;比较当前节点的值&#xff0c;将较小的节点添加到结果链表中。 具体思路是这样的&#xff1a; 首先创建一个哑节点(dummy node)作为合并后链表的头部&#xff0c;这样可以简…

ES01-环境安装

ES01-环境安装 文章目录ES01-环境安装1-参考网址2-知识总结1-参考网址 elasticsearch官网地址&#xff1a;https://www.elastic.co/安装elasticsearch9.0.0参考&#xff1a;https://zhuanlan.zhihu.com/p/1920780524991017021安装elasticsearch9.0.0参考&#xff1a;http://ww…

UI前端大数据可视化实战策略:如何设计符合用户认知的数据可视化界面?

hello宝子们...我们是艾斯视觉擅长ui设计、前端开发、数字孪生、大数据、三维建模、三维动画10年经验!希望我的分享能帮助到您!如需帮助可以评论关注私信我们一起探讨!致敬感谢感恩!UI前端大数据可视化实战策略&#xff1a;如何设计符合用户认知的数据可视化界面&#xff1f;数…

学习python第15天

其实前面学的根本不记得了&#xff0c;小丑.jpg&#xff0c;如果真的面试问到了估计也是一脸懵今日任务&#xff1a;JSON先认识一下JSON和JSONL文件记得之前在面试KIMI的时候&#xff0c;面试官就给我出了JSONL和EXCEL转换的手撕代码题&#xff0c;而那个时候&#xff0c;我连什…