将另一个函数作为参数,或将函数定义为返回值的函数称为高阶函数。JavaScript可以接受高阶函数。这种处理高阶函数的能力以及其他特性使JavaScript成为非常适合函数式编程的编程语言之一。JavaScript将函数视为一等公民您可能听说过JavaScript函数是一等公民。这意味着,函数是JavaScript中的对象。它们的类型是Object,可以作为变量的值进行赋值,可以像其他引用变量一样进行传递和返回。一等函数赋予JavaScript特殊的能力,使我们能够从高阶函数中获益。由于函数是对象,而JavaScript是一种流行的编程语言,因此它支持函数式编程的本机方法。事实上,一等函数是JavaScript原生方法。我敢打赌你在使用它们时甚至没有想过你在使用函数。高阶函数接受函数作为参数如果您进行了大量的JavaScript开发,您可能遇到过使用回调函数的情况。回调函数是在所有其他操作完成后在操作结束时执行的函数。通常,我们将此函数作为最后一个参数传递,在其他参数之后。它通常被定义为一个内联匿名函数。回调函数依赖于JavaScript处理高阶函数的能力。JavaScript是一种单线程语言。这意味着一次只能执行一个操作。为了避免操作或系统的主线程相互阻塞(这会导致死锁),引擎确保所有操作按顺序执行。它们沿着这个单一线程排队,直到可以安全地生成另一个代码事务。将函数作为参数传入并在父函数的其他操作完成后运行该函数的能力对于支持高阶函数的语言来说至关重要。JavaScript中的回调函数允许异步行为,因此脚本可以在等待结果的同时继续执行其他函数或操作。在处理可能在不确定的时间段后返回结果的资源时,传递回调函数的能力至关重要。这种高阶函数模式在Web开发中非常有用。脚本可以向服务器发送请求,然后需要在响应到来时对其进行处理,而无需了解服务器的网络延迟或处理时间。Node.js通常使用回调函数来有效地利用服务器资源。这种异步方法对于在执行函数之前等待用户输入的应用程序也很有用。考虑将事件侦听器添加到按钮的这个简单的JavaScript代码段。document.getElementById("clicker").addEventListener("click",function(){alert("youtriggered"+this.id);});此脚本使用内联匿名函数来显示警报。但它也可以很容易地使用一个单独定义的函数并将这个命名函数传递给addEventListener方法。varproveIt=function(){alert("youtriggered"+this.id);};document.getElementById("clicker").addEventListener("click",proveIt);我们这样做不仅是为了展示高阶函数。我们使代码更具可读性、更具弹性,并为不同的任务(监听点击事件与提醒用户)分离功能。代码可重用性我们的proveIt()函数在结构上独立于其周围的代码,始终返回被触发元素的ID。这种函数设计方法是函数式编程的核心。此代码可以存在于您显示带有元素ID的警报的任何上下文中,并且可以由任何事件侦听器调用。用单独定义和命名的函数替换内联函数的能力开辟了无限的可能性。在函数式编程中,我们尝试开发不改变外部数据的纯函数,并且每次都为相同的输入返回相同的结果。现在我们有了一个基本工具,可以帮助我们开发一个小型的、有针对性的高阶函数库,您可以在任何应用程序中使用它。请注意,我们将proveIt而不是proveIt()传递给我们的addEventListener函数。当您传递不带括号的函数名称时,您传递的是函数对象本身。当您在括号中传递一个函数时,您传递的是执行该函数的结果。返回函数除了将函数作为参数外,JavaScript还允许函数将其他函数作为结果返回。这是有道理的,因为函数是简单的对象。对象(包括函数)可以定义为函数的返回值,就像字符串、数组或其他值一样。但是函数返回结果意味着什么?函数是分解问题和创建可重用代码片段的强大方法。当我们将函数定义为高阶函数的返回值时,它充当新函数的模板。假设您读了太多有关“千禧一代”的内容而感到无聊。你决定无论何时出现“千禧一代”这个词,你都会用“蛇人”来代替它。您可以简单地编写一个函数,对您传递给它的任何文本执行该文本替换。varsnakeify=function(text){returntext.replace(/millenials/ig,"SnakePeople");};console.log(snakify("TheMillenialsarealwaysupsomething."));//蛇人总是在搞什么鬼。这种写法是有效的,但不够通用。您可能想为其他情况编写替换函数:varhippify=function(text){returntext.replace(/babyboomers/ig,"AgingHippies");};console.log(hippify("TheBabyBoomersjustlooktheotherway."));//TheAgingHippiesjustlookotherway.但是,如果您决定做一些更复杂的事情来保留原始字符串中的大小写怎么办?您将必须修改您的两个新功能才能执行此操作。这很麻烦,并且会使您的代码更加脆弱和难以阅读。在这种情况下,我们可以使用高阶函数作为解决方案。对于高阶函数模板,您真正想要的是能够灵活地用模板函数中的任何其他术语替换任何术语,并将该行为定义为您可以在其上构建新自定义函数的基本函数。有了指定函数作为返回值的能力,JavaScript提供了一种使这种情况更方便的方法:;};};varsnakify=attitude(/millenials/ig,"SnakePeople");varhippify=attitude(/babyboomers/ig,"AgingHippies");console.log(snakify("TheMillenialsarealwaysuptosomething."));//属蛇的人总是在搞事情。安慰。log(hippify("婴儿潮一代只是另眼相看。"));//上了年纪的嬉皮士只是另眼相看。我们所做的是将执行实际工作的代码隔离到一个通用的、可扩展的态度函数中。它封装了修改任何输入字符串所需的所有工作:使用原始短语作为初始值,并输出具有某种态度的替换短语。当我们将这个新函数定义为对态度高阶函数的引用时,我们会得到什么,预填充它接收到的前两个参数?它允许新函数获取您传递给它的任何文本,并将该参数用作我们定义的返回函数中态度函数的输出。JavaScript函数不关心传递给它们的参数的数量。如果缺少第二个参数,函数会将其视为未定义。当我们选择不提供第三个参数或任何数量的附加参数时,它也会这样做。此外,您可以稍后传入该额外参数。您可以在定义要调用的高阶函数后执行此操作,如刚才所示。我们正在创建一个模板高阶函数来返回另一个函数。然后我们定义这个新返回的函数,减去一个属性,作为模板函数的自定义实现。您以这种方式创建的所有函数都将继承高阶函数的工作代码。但是,您可以使用不同的默认参数预定义它们。使用高阶函数高阶函数对于JavaScript的工作方式至关重要,并且您已经在使用它们。每当你传递一个匿名函数或回调函数时,你实际上是在使用传递函数的返回值作为另一个函数(例如箭头函数)的参数。开发人员在JavaScript学习的早期就熟悉高阶函数。它是JavaScript设计中固有的,所以你只需要在后面学习驱动箭头函数或回调的概念。为返回其他函数的函数赋值的能力扩展了JavaScript的便利性。高阶函数允许我们创建自定义命名函数,这些函数使用一阶函数的共享模板代码来执行专门的任务。这些函数中的每一个都可以继承对高阶函数所做的任何改进。这有助于我们避免代码重复并保持我们的源代码清洁和可读。如果你确定你的函数是纯函数(它们不会改变外部值并且总是为任何给定的输入返回相同的值),你可以创建测试来验证当你更新一阶函数时,你的代码不会'改变会破坏任何东西。总结现在您知道了高阶函数的工作原理,您可以开始考虑如何在您自己的项目中利用这个概念。JavaScript的优点之一是您可以将函数式技术与您已经熟悉的代码混合使用。即使您一开始只是使用高阶函数,您也会很快熟悉它们提供的额外灵活性。现在使用高阶函数做一点工作可以在未来几年改进你的代码。以上就是本文的全部内容,感谢阅读~
