前言本文将带你了解JavaScript的箭头函数。我们将向您展示如何使用ES6的箭头语法,以及在代码中使用箭头函数时要注意的一些常见错误。您会看到大量有关它们如何工作的示例。JavaScript中的箭头函数随着ECMAScript2015(也称为ES6)的发布而出现。由于简洁的语法和对this关键字的处理,箭头函数很快成为开发人员的最爱。箭头函数语法函数就像食谱,您可以在其中存储有用的指令来执行您需要在程序中发生的事情,例如执行操作或返回值。通过调用函数执行配方中包含的步骤。您可以在每次调用该函数时执行此操作,而无需一次又一次地重写配方。下面是在JavaScript中声明和调用函数的标准方法://函数声明functionsayHiStranger(){return'Hi,stranger!'}//调用函数sayHiStranger()您也可以将相同的函数编写为函数表达式,就好了这样:constsayHiStranger=function(){return'Hi,stranger!'}JavaScript箭头函数总是表达式。以下是如何使用箭头符号重写上述函数:constsayHiStranger=()=>'Hi,stranger'这样做的好处包括:只有一行代码没有function关键字没有return关键字没有大括号{}在JavaScript中,函数是一等公民。您可以将函数存储在变量中,将它们作为参数传递给其他函数,并作为值从其他函数返回。您可以使用JavaScript箭头函数完成所有这些事情。无括号语法在上面的例子中,函数没有参数。在这种情况下,您必须在粗箭头符号(=>)之前添加一对空括号()。当有多个参数时同样适用:constgetNetflixSeries=(seriesName,releaseDate)=>`The${seriesName}serieswasreleasedin${releaseDate}`//callthefunctionconsole.log(getNetflixSeries('Bridgerton','2020'))//输出:2020年发布的Bridgerton系列如果只有一个参数,可以省略括号(不一定要,但是可以):constfavoriteSeries=seriesName=>seriesName==="布里杰顿”?"Let'swatchit":"Let'sgoout"//调用函数console.log(favoriteSeries("Bridgerton"))//output:"Let'swatchit"执行此操作时要小心。例如,如果您决定使用默认参数,则必须将它们括在圆括号中://withtheparentheses:correctconstbestNetflixSeries=(seriesName="Bridgerton")=>`${seriesName}isthebest`//outputs:"Bridgertonisthebest"console.log(bestNetflixSeries())//没有括号:错误constbestNetflixSeries=seriesName="Bridgerton"=>`${seriesName}isthebest`//UncaughtSyntaxError:invalidarrow-functionarguments(parenthesesaround箭头函数可能会有所帮助)当隐式返回在函数体中只有一个表达式时,您可以使ES6的箭头语法更加简洁。您可以将所有内容放在一行中,去掉大括号,并删除return关键字。您已经在上面的示例中看到了这些漂亮的单行代码是如何工作的。下面的orderByLikes()函数返回一个Netflix剧集对象数组,按最高点赞数排序://使用JSsort()函数根据点赞数按降序对标题进行排序//(更多点赞在顶部,底部较少constorderByLikes=netflixSeries.sort((a,b)=>b.likes-a.likes)//调用函数//输出:标题和点赞数按降序排列console。log(orderByLikes)这种写法很酷,但是要注意代码的可读性。尤其是在使用单行和无括号的ES6箭头语法对一堆箭头函数进行排序时。就像这个例子:constgreeter=greeting=>name=>`${greeting},${name}!`那里发生了什么?尝试使用常规函数语法:一个匿名函数。这个内部函数接受另一个名为name的参数,并使用greeting和name的值返回一个字符串。该函数的调用方式如下:constmyGreet=greeter('Goodmorning')console.log(myGreet('Mary'))//输出:“Goodmorning,Mary!”当你的JavaScript箭头函数包含多个语句时,请注意隐式返回错误,你需要将所有语句包裹在花括号中并使用return关键字。在下面的代码中,该函数构建了一个包含多个Netflix剧集的标题和摘要的对象://显式返回返回容器})。map()函数中的箭头函数在一系列语句中展开,语句结束时返回一个对象。这使得在函数体周围使用花括号是不可避免的。此外,由于使用了花括号,因此隐式返回不是一种选择。您必须明确使用return关键字。如果您的函数使用隐式返回返回对象字面量,则需要将对象字面量括在括号中。不这样做会导致错误,因为JavaScript引擎会错误地将对象文字花括号解析为函数花括号。正如您刚刚注意到的,当您在箭头函数中使用花括号时,您不能省略return关键字。上述代码的较短版本演示了此语法://UncaughtSyntaxError:uncaughtSyntaxError:uncaughttoken:':'constseriesList=netflixSeries.map(series=>{title:series.name});//工作正常constseriesList=netflixSeries.地图(系列=>({标题:系列名称}));箭头函数不能命名在函数关键字和参数列表之间没有名称的函数称为匿名函数。这是常规匿名函数表达式的样子:constanonymous=function(){return'Youcan\'tidentifyme!'}箭头函数都是匿名函数:constanonymousArrowFunc=()=>'Youcan\'tidentifyme!'从ES6开始,变量和方法可以使用name属性通过匿名函数的句法位置来推断它们的名称。这使得在检查其值或报告错误时识别函数成为可能。用anonymousArrowFunc查看:console.log(anonymousArrowFunc.name)//output:"anonymousArrowFunc"注意,推断的name属性只有在匿名函数赋值给变量时才存在,如上例。如果你使用匿名函数作为回调,你就失去了这个有用的功能。在下面的演示中,.setInterval()方法中的匿名函数无法利用name属性:letcounter=5letcountDown=setInterval(()=>{console.log(counter)counter--if(counter===0){console.log("Ihavenoname!!")clearInterval(countDown)}},1000)这还不是全部。这个推断的名称属性仍然不能作为一个适当的标识符工作,您可以使用它来引用函数本身——例如递归、解除绑定事件等。如何处理this关键字关于箭头函数的最重要的事情之一是他们处理this关键字的方式。特别是,箭头函数中的this关键字不会反弹。为了说明这意味着什么,请查看下面的演示。这里有一个按钮。单击该按钮会触发一个从5到1的反向计数器,该计数器显示在按钮本身上。开始计数器...conststartBtn=document.querySelector(".start-btn");startBtn.addEventListener('click',function(){this.classList.add('counting')letcounter=5;consttimer=setInterval(()=>{this.textContent=countercounter--if(counter<0){this.textContent='结束!'this.classList.remove('counting')clearInterval(timer)}},1000)})请注意,.addEventListener()方法中的事件处理程序是常规匿名函数表达式,而不是箭头函数。为什么?如果您在函数内打印this的值,您会看到它指的是侦听器连接到的按钮元素,这正是我们所期望的,也是程序按计划工作所需要的:startBtn.addEventListener('click',function(){console.log(this)...})这是它在FirefoxDeveloperTools控制台中的样子:然后,尝试使用箭头函数而不是常规函数,如下所示:startBtn.addEventListener('click',()=>{console.log(this)...})现在,this不再引用按钮元素。相反,它指的是Window对象:这意味着如果您想在单击按钮后使用它向按钮添加一个类,您的代码将不起作用://更改按钮的边框外观this.classList.add('counting')这是控制台中的错误消息:当您在JavaScript中使用箭头函数时,不会重新绑定this关键字的值。它继承自父作用域(也称为词法作用域)。在这种特殊情况下,箭头函数作为参数传递给全局范围内的startBtn.addEventListener()方法。因此,函数处理程序中的this也绑定到全局范围——即Window对象。因此,如果您希望this指向应用中的开始按钮,正确的做法是使用常规函数,而不是箭头函数。匿名箭头函数在上面的演示中,接下来要注意的是.setInterval()方法中的代码。在这里,您也会发现一个匿名函数,但这次是箭头函数。为什么?请注意,如果您使用常规函数,该值将如何:consttimer=setInterval(function(){console.log(this)...},1000)是按钮元素吗?并不真地。这个值将是Window对象!事实上,上下文已经改变,因为现在this在未绑定或全局函数中,它作为参数传递给.setInterval()。因此,this关键字的值也发生了变化,因为它现在绑定到全局范围。在这种情况下,一个常见的技巧是包含另一个变量来存储this关键字的值,以便它始终指向预期的元素-在这种情况下,按钮元素:constthat=thisconsttimer=setInterval(function(){console.log(that)...},1000)你也可以使用.bind()来解决这个问题:consttimer=setInterval(function(){console.log(this)...}.bind(this),1000)使用箭头函数,问题完全消失。这是使用箭头函数时this的值:consttimer=setInterval(()=>{console.log(this)...},1000)这一次,控制台打印了按钮,这就是我们想要的。事实上,程序想要更改按钮的文本,所以它需要this来引用按钮元素:consttimer=setInterval(()=>{console.log(this)//按钮的文本显示计时器值this。textContent=counter},1000)箭头函数没有自己的this上下文。他们从他们的父母那里继承了this的值,也正是因为这个特点,他们在上面的案例中是一个不错的选择。行不通的事情箭头函数不仅仅是在JavaScript中编写函数的一种奇特的新方法。它们有自己的局限性,这意味着在某些情况下您不想使用箭头函数。让我们再看一些例子。作为对象方法的箭头函数箭头函数不能很好地用作对象方法。考虑netflixSeries对象,它具有一些属性和一组方法。调用console.log(netflixSeries.getLikes())应该打印一条消息,说明当前的点赞数。console.log(netflixSeries.addLike())应该添加一个赞,然后在控制台上打印新值:constnetflixSeries={title:'AfterLife',firstRealease:2019,likes:5,getLikes:()=>`${this.title}有${this.likes}个赞`,addLike:()=>{this.likes++return`感谢您喜欢${this.title},它现在有${this.likes}个赞`}}相反,调用.getLikes()方法返回“undefinedhasNaNlikes”,调用.addLike()方法返回“Thankyouforlikingundefined,whichnowhasNaNlikes”。因此,this.title和this.likes无法分别引用对象的属性title和likes。这一次,问题是箭头函数的词法作用域。对象方法中的this指的是父对象的范围,在本例中是Window对象,而不是父对象本身——也就是说,不是netflixSeries对象。当然,解决方案是使用常规函数:constnetflixSeries={title:'AfterLife',firstRealease:2019,likes:5,getLikes(){return`${this.title}has${this.likes}likes`},addLike(){this.likes++return`Thankyouforliking${this.title},whichnowhas${this.likes}likes`}}//调用方法console.log(netflixSeries.getLikes())console.log(netflixSeries.addLike())//输出:AfterLife有5个赞谢谢你喜欢AfterLife,它现在有6个likes方法调用,所以这个值将指向一些有用的东西。例如,在JQuery事件处理程序中,这将使您能够访问处理程序绑定到的DOM元素:$('body').on('click',function(){console.log(this)})//但如果我们使用箭头函数,正如我们所见,它没有自己的this上下文,我们会得到意想不到的结果:$('body').on('click',()=>{console.log(this)})//Window以下是使用Vue的其他示例:newVue({el:app,data:{message:'Hello,World!'},created:function(){console.log(this.message);}})//你好,世界!在创建的钩子中,它被绑定到Vue实例,所以'Hello,World!'将显示消息。但是,如果我们使用箭头函数,this将指向父作用域,它上面没有message属性:newVue({el:app,data:{message:'Hello,World!'},created:()=>{console.log(this.message);}})//undefinedarrowfunctionhasnoargumentsobject有时,您可能需要创建一个具有无限数量参数的函数。例如,假设您要创建一个函数来列出您最喜爱的Netflix节目,并按偏好排序。但是,您还不知道要包括多少集。JavaScript提供了参数对象。这是一个类似数组的对象(不是完整数组),用于存储调用时传递给函数的值。尝试使用箭头函数来实现它:constlistYourFavNetflixSeries=()=>{//我们需要将参数转换成一个真正的数组//所以我们可以使用.map()constfavSeries=Array.from(arguments)returnfavSeries.map((series,i)=>{return`${series}ismy#${i+1}favoriteNetflixseries`})console.log(arguments)}console.log(listYourFavNetflixSeries('Bridgerton','Ozark','AfterLife'))调用该函数时,会出现以下错误:UncaughtReferenceError:argumentsisnotdefined。这意味着arguments对象在箭头函数中不可用。事实上,只需将箭头函数替换为常规函数即可:#${i+1}最喜欢的Netflix系列`})console.log(arguments)}console.log(listYourFavNetflixSeries('Bridgerton','Ozark','AfterLife'))//output:["Bridgertonismy#1最喜欢的Netflix系列”,“Ozark是我最喜欢的Netflix系列第2名”,“AfterLife是我最喜欢的Netflix系列第3名”]所以如果你需要参数对象,你不能使用箭头函数。但是如果你真的想用箭头函数复制相同的功能怎么办?您可以使用ES6剩余参数(...)。以下是重写函数的方法:constlistYourFavNetflixSeries=(...seriesList)=>{returnseriesList.map((series,i)=>{return`${series}ismy#${i+1}favoriteNetflixseries`})}总结通过使用箭头函数,你可以写一行带有隐式返回的代码来解决JavaScript中this关键字的绑定问题。箭头函数也适用于数组方法,例如.map()、.sort()、.forEach()、.filter()和.reduce()。但请记住:箭头函数并不能替代常规的JavaScript函数。请记住,箭头函数只有在它是正确的工具时才应该使用。以上就是本文的全部内容。如果对你有帮助,请点赞收藏转发~