Web-Dev-For-Beginners JS 基础精讲从函数声明到高阶函数的 JavaScript 方法与函数完全指南【免费下载链接】Web-Dev-For-Beginners24 Lessons, 12 Weeks, Get Started as a Web Developer项目地址: https://gitcode.com/GitHub_Trending/we/Web-Dev-For-Beginners本文基于 Web-Dev-For-Beginners 课程2-js-basics模块的「Methods and Functions」一节系统讲解 JavaScript 中函数Function与方法Method的核心概念声明与调用、参数与实参、默认值、返回值、函数作为参数高阶函数以及匿名函数与箭头函数三种语法风格的选择策略。读完本文你不仅能独立完成课程配套的「Fun with Functions」练习和mathUtils.js工具库挑战还能在仓库内的 Terrarium、打字游戏、太空射击游戏等真实项目源码中印证这些概念的实际落地方式。为什么需要函数把重复逻辑打包成可复用组件重复编写同一段代码是编程中最常见的烦恼之一。函数function解决了这个问题它允许你把代码打包成一个可复用的块。课程的类比很形象——函数就像让福特装配线革命化的标准件一旦你做出了一个可靠的组件就可以在任何需要的地方使用而不必从零重建。函数让你把代码片段捆绑起来在程序的任何位置重复调用。与其把同样的逻辑到处复制粘贴不如一次创建函数、随时调用。这样做有两个直接收益代码保持整洁、组织有序后续维护更容易——试想如果一段逻辑散落在代码库的 20 个地方修改时会有多大的维护成本。课程还特别强调命名即文档给函数起一个描述性的名字至关重要。当你看到cancelTimer()时立刻就能明白它是干什么的就像清楚标注的按钮告诉你点击后会发生什么一样。函数Function与方法Method的区别课程原文明确指出你在整个课程中其实一直在使用方法。console.log()就是一个方法——本质上是属于console对象的一个函数。关键区别在于函数是独立存在的代码块方法是挂载在对象上的函数调用时通过对象访问对象.方法()。许多开发者在口语中会混用这两个术语但理解「方法依附于对象」这一点是后续学习 DOM APIdocument.getElementById()、数组方法map()、filter()的基础。课程挑战Challenge能否用一句话概括函数和方法的区别答案要点函数独立存在方法是属于某个对象、通过该对象调用的函数。创建和调用函数语法结构函数定义遵循一致的模式function nameOfFunction() { // function definition // function definition/body }逐部分拆解function关键字告诉 JavaScript「嘿我在创建一个函数」nameOfFunction是函数描述性名称的位置圆括号()是放置参数parameters的位置花括号{}包含调用该函数时实际执行的代码。一个最小示例displayGreetingfunction displayGreeting() { console.log(Hello, world!); }这个函数把 Hello, world! 打印到控制台。定义之后你可以按需使用任意多次。要**执行调用**函数写出函数名后紧跟括号// calling our function displayGreeting();执行这一行时函数体内所有代码都会被执行浏览器控制台显示 Hello, world!。你甚至可以反复调用同一个函数。一个重要的 JavaScript 特性JavaScript 允许你先定义函数、后调用它也可以先写调用、后写定义函数声明会被提升hoistingJavaScript 引擎会处理执行顺序。命名最佳实践课程给出的三条实用建议给函数起清晰、有描述性的名字——未来的你会感谢现在的自己多词名称使用驼峰命名法camelCasing如calculateTotal而不是calculate_total让每个函数专注于做好一件事。实战印证仓库中 Terrarium 项目的解决方案 script.js 恰好体现了「一次定义、多次复用」——dragElement函数只定义了一次script.js 处function dragElement(terrariumElement) {...}随后被连续调用 14 次让plant1到plant14这 14 个盆栽元素全部获得拖拽能力。如果不用函数就得复制 14 份几乎相同的拖拽代码。向函数传递信息参数Parameters与实参ArgumentsdisplayGreeting只输出固定的 Hello, world!能力有限。参数让函数变得灵活它们是占位符每次调用时都可以填入不同的值同一个函数因此能在不同调用中处理不同信息。定义函数时把参数列在括号里多个参数用逗号分隔function name(param, param2, param3) { }更新后的问候函数接受一个名字参数function displayGreeting(name) { const message Hello, ${name}!; console.log(message); }注意这里用反引号和${}把变量直接拼进字符串——这是模板字符串template literal是混入变量构建字符串的便捷方式。调用时传入任意名字即可displayGreeting(Christopher); // 运行时输出 Hello, Christopher!JavaScript 会把字符串Christopher赋给name参数再构造出 Hello, Christopher! 这条个性化消息。参数可以是任何类型字符串、数字、布尔值、对象甚至函数。实战印证4-typing-game/solution/index.js 中的renderQuote函数就是一个典型的带参数函数——它接受quote字符串参数内部用模板字符串逐词渲染成带高亮类的span而 index.js 的messages.success更是把「函数作为配置项」和模板字符串结合了起来success: (seconds) \ Congratulations! You finished in ${seconds.toFixed(2)} seconds.。参数的信息流课程用流程图总结了参数的工作方式用文字表述就是函数调用 displayGreeting(Alice) → 参数绑定name Alice → 函数体执行Hello, ${name}! 模板拼接 → 产出结果Hello, Alice!概念核对参数parameter是定义函数时声明的占位符实参argument是调用时实际传入的值。多传的实参会被函数忽略传少了则对应参数为undefined。默认值让参数可选如果想让某些参数变成可选的就用默认值default values。以「允许自定义问候词、未指定时回退到 Hello」为例用等号即可设置默认值和普通变量赋值写法一致function displayGreeting(name, salutationHello) { console.log(${salutation}, ${name}); }这里name仍然是必需的而salutation在调用者没有提供时使用备用值Hello。于是同一个函数有两种调用方式displayGreeting(Christopher); // 输出 Hello, Christopher使用默认值 displayGreeting(Christopher, Hi); // 输出 Hi, Christopher使用自定义值第一次调用中 JavaScript 使用默认的 Hello第二次则使用自定义的 Hi。这种灵活性让函数能适应不同场景。进阶提示默认参数让函数更易用——调用者可以用合理默认值快速上手需要定制时再传参同时保持向后兼容。实战印证太空游戏的 app.js 把默认参数用到了极致const $ (sel, ctx document) ctx.querySelector(sel); const $$ (sel, ctx document) Array.from(ctx.querySelectorAll(sel));ctx的默认值是document因此$(#myCanvas)默认在全局查找需要限定作用域时才传第二个参数。从源码结构看这是「默认参数 箭头函数 返回值」三个概念的组合应用。返回值让函数把结果交还给你前面的函数只是往控制台打印消息。如果希望函数计算出某个结果并交还给你呢这就是**返回值return values**的用途函数可以把一个值交还给调用方你可以把它存进变量或在代码的其他地方使用。用return关键字加上要返回的值return myVariable;关键行为当函数执行到return语句时会立即停止运行并把该值送回给调用者。把问候函数改成「返回消息」而不是「打印消息」function createGreetingMessage(name) { const message Hello, ${name}; return message; }现在这个函数构造消息并把它交还给你。用变量接收返回值const greetingMessage createGreetingMessage(Christopher);此时greetingMessage包含 Hello, Christopher你可以把它用在任何地方——显示在网页上、写进邮件、传给另一个函数。函数如果没有return语句会隐式返回undefined。关键洞察返回值的函数更通用因为由调用方决定如何处置结果这让代码更具模块化和可复用性。实战印证typing-game 的 index.js 中const getRandomQuote () quotes[Math.floor(Math.random() * quotes.length)];是一个箭头函数形式的「纯计算、返回结果」函数它不直接操作 UI而是把随机选中的一句名言交还给调用者由 startGame 决定拿它做什么。返回值让「取数据」和「用数据」分离正是课程所说模块化思想的体现。函数作为函数的参数高阶函数函数可以被当作参数传给另一个函数。这个概念初看复杂却是非常强大的特性支撑起灵活的编程模式。这种模式最典型的应用场景是表达「当某事发生时执行另一件事」比如「定时器结束时运行这段代码」「用户点击按钮时调用这个函数」。课程用内置函数setTimeout演示——它等待指定时间后执行一段代码你需要告诉它「执行什么」正好适合传入一个函数function displayDone() { console.log(3 seconds has elapsed); } // timer value is in milliseconds setTimeout(displayDone, 3000);注意我们传给setTimeout的是displayDone不带括号——我们并没有自己调用它而是把它「移交」给setTimeout说「3 秒后调用它」。如果写成setTimeout(displayDone(), 3000)则是立即调用并把返回值这里是undefined传过去行为完全不同。实战印证一事件回调Terrarium 的 dragElement 内部就是高阶用法的教科书案例terrariumElement.onpointerdown pointerDrag;把内部函数pointerDrag交给元素作为指针按下事件的回调随后document.onpointermove elementDrag;、document.onpointerup stopElementDrag;又分别注册了移动与松手回调。实战印证二Promise 回调浏览器扩展项目的 index.js 中axios.get(...).then((response) { ... })把处理响应的箭头函数交给 Promise 的then方法这正是「当某事数据到达发生时执行另一件事渲染结果」的同款模式。此外 index.js 里let num (element) element closestNum; co2Scale.findIndex(num);也是把函数作为参数传给数组方法findIndex——从源码结构看这是高阶函数在浏览器环境中的日常形态。匿名函数有时你只为一次用途需要函数不想为它命名——只用一次的函数何必额外占用一个名字JavaScript 允许创建匿名函数anonymous functions没有名字、直接在使用处定义的函数。用匿名函数重写定时器示例setTimeout(function() { console.log(3 seconds has elapsed); }, 3000);效果完全相同但函数直接定义在setTimeout调用内部省去了独立的函数声明。箭头函数Arrow Functions现代 JavaScript 提供了更简洁的函数写法——箭头函数使用长得像箭头。它允许你省略function关键字写出更紧凑的代码。setTimeout(() { console.log(3 seconds has elapsed); }, 3000);结构拆解()是放参数的位置本例为空然后是箭头最后是花括号包裹的函数体。功能与之前完全一致只是语法更简洁。实战印证打字游戏项目整体就是箭头函数风格。index.js 中连续定义了四个箭头函数工具getRandomQuote取随机引语、renderQuote渲染引语、highlightWord高亮当前词index.js 的handleTyping处理每次击键。而太空游戏的 app.js 则用(() { ... })()立即执行函数表达式IIFE把整个游戏封装在独立的箭头函数作用域内——从源码结构看这是一种避免污染全局命名空间的常用组织手法。何时选择哪种写法课程给出的实用准则风格形态特点适用场景传统命名函数function name() {}具名、可被提升hoisted需要在多处复用的函数箭头函数const name () {}简洁、现代风格短回调、工具函数现代代码库中最常见匿名函数function() {}无名字、就地定义一次性使用的事件处理器等如果函数会被多次使用就给它命名并独立定义如果只是某个单一用途考虑匿名或内联箭头函数。传统语法与箭头函数都是有效选择只是箭头函数在现代代码库中更为普遍。现代趋势因为简洁箭头函数正成为许多开发者的默认选择但传统函数依然有其位置。项目内函数用法的横向对照仓库里几个项目的解决方案恰好覆盖本节的每个知识点适合作为自检清单知识点文档示例仓库印证文件与位置一次定义、多次调用displayGreeting()script.jsdragElement调用 14 次参数 模板字符串displayGreeting(name)index.jsrenderQuote(quote)默认参数salutationHelloapp.js(sel, ctx document)返回值createGreetingMessageindex.jsgetRandomQuote函数作为参数setTimeout(displayDone, 3000)index.jsfindIndex(num)script.js事件回调赋值匿名/箭头回调setTimeout(() {...}, 3000)index.js.then((response) {...})index.jsaddEventListener(click, startGame)闭包延伸—script.js 注释明确说明dragElement内部函数捕获外层pos1~pos4状态正是后续课程「闭包」概念的雏形实战练习Fun with Functions 作业课程配套作业 assignment.md「Fun with Functions」要求创建一个名为functions-practice.js的文件分五个部分巩固本节全部概念Part 1基础函数sayHello不接受任何参数仅向控制台打印 Hello!。introduceYourself接受name参数打印类似 Hi, my name is [name] 的消息。Part 2带默认参数的函数greetPerson接受两个参数——name必需和greeting可选默认 Hello打印 [greeting], [name]! 格式的消息。Part 3返回值的函数addNumbers接受num1和num2两个参数返回它们的和。createFullName接受firstName和lastName参数返回拼合后的完整姓名单个字符串。Part 4综合运用calculateTip接受billAmount必需和tipPercentage可选默认 15两个参数计算并返回小费金额。Part 5测试你的函数为每个函数添加调用并用console.log()展示结果。作业给出的示例测试调用// Test your functions here sayHello(); introduceYourself(Sarah); greetPerson(Alex); greetPerson(Maria, Hi); const sum addNumbers(5, 3); console.log(The sum is: ${sum}); const fullName createFullName(John, Doe); console.log(Full name: ${fullName}); const tip calculateTip(50); console.log(Tip for $50 bill: $${tip});提示按 F12 打开浏览器开发者控制台即可看到console.log()的输出。评分标准Rubric摘要作业定义了五个维度的评分标准函数创建6 个函数是否语法正确、命名规范、参数与默认值必需/可选参数与默认值是否符合规格、返回值该返回的函数正确返回不该返回的只做动作、代码质量组织清晰、命名有意义、缩进规范、测试所有函数都有恰当测试且结果展示清晰。加分挑战可选把其中一个函数改写成箭头函数版本创建一个接受另一个函数作为参数的函数类似课程中setTimeout的示例增加输入校验让函数能妥善处理无效输入。进阶挑战用 Agent 模式构建 mathUtils.js课程还设计了一个 GitHub Copilot Agent 模式的挑战创建一个演示本节全部概念的数学工具库mathUtils.js包含以下函数add接受两个参数返回它们的和multiply带默认参数值第二个参数默认为 1square箭头函数接受一个数字并返回其平方calculate接受一个函数作为参数和两个数字然后对该两个数字应用这个函数用合适的测试用例演示调用每个函数。参照课程的概念一个符合规格的实现大致如下自行在本地环境编写运行// mathUtils.js — 演示本节全部函数概念 // 1. 基础参数 返回值 function add(a, b) { return a b; } // 2. 默认参数 function multiply(a, b 1) { return a * b; } // 3. 箭头函数 const square (n) n * n; // 4. 函数作为参数高阶函数 function calculate(fn, a, b) { return fn(a, b); } // 5. 测试用例 console.log(add(2, 3)); // 5 console.log(multiply(4)); // 4b 使用默认值 1 console.log(square(5)); // 25 console.log(calculate(add, 2, 3)); // 5 console.log(calculate(multiply, 4, 5)); // 20其中calculate就是「函数作为参数」概念的最小实用形态它本身不关心具体运算只负责「应用你交给我的那个函数」调用方通过传入不同的函数决定行为——这与 Terrarium 中「事件发生 → 执行回调」的模式在结构上是同一件事。复习与进阶学习路径课程建议重点复习箭头函数——它们在代码库中的使用率持续上升。练习方法先按传统语法写一个函数再把它改写成箭头函数语法。按照课程给出的进阶节奏一个合理的练习路径是起步几十分钟内写一个返回你最喜欢的数字的简单函数写一个两参数求和函数把一个传统函数改写成箭头函数完成「函数 vs 方法」的一句话挑战。本周构建上面的mathUtils.js工具库完成「Fun with Functions」作业的全部 6 个函数写一个以另一个函数为参数的函数练习默认参数与模板字符串返回值。进阶把写过的重复代码重构为可复用函数只用函数不用全局变量搭一个小计算器用箭头函数配合map()、filter()练习数组方法研究高阶函数与函数式编程概念在闭包与作用域仓库 Terrarium 的dragElement是天然的闭包示例上深入构建大量使用函数组合的项目。小结函数工具箱把本节的知识浓缩成一张对照表概念关键语法核心要点函数声明function name() {}描述性命名camelCase、一次定义、多次复用、可提升方法obj.method()挂在对象上的函数如console.log()参数function f(a, b) {}占位符调用时传入的实参可以是任意类型默认值function f(a, b 1) {}参数可选、保持向后兼容返回值return value;遇到return立即退出并交还值调用方决定用途模块化更强高阶函数setTimeout(fn, ms)、findIndex(fn)函数可作参数传递表达「当 X 发生时做 Y」匿名函数function() {}一次性用途、无需命名箭头函数const f (a) ...简洁现代短回调首选函数的收益可以归结为四点代码可复用、组织更清晰、更易测试、支持模块化设计。正如课程结语所言函数是更大程序的构建块——你未来构建的每一个应用都会用函数来组织、复用和结构化代码。掌握把逻辑打包成可复用组件的能力就是进入模块化编程世界的入口。【免费下载链接】Web-Dev-For-Beginners24 Lessons, 12 Weeks, Get Started as a Web Developer项目地址: https://gitcode.com/GitHub_Trending/we/Web-Dev-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
