您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > javascript

JavaScript 中的箭头函数:如何使用 Fat & Concise 语法香草

时间:2022-03-11 11:17:07  来源:  作者:走马Z

了解有关 JAVAScript 箭头函数的所有信息。我们将向您展示如何使用 ES6 箭头语法,以及在代码中使用箭头函数时需要注意的一些常见错误。你会看到很多例子来说明它们是如何工作的。

JavaScript 箭头函数随着 ECMAScript 2015(也称为 ES6)的发布而出现。由于其简洁的语法和对this关键字的处理,箭头函数很快成为开发人员最喜欢的功能。

箭头函数语法:重写常规函数

函数就像食谱一样,您可以在其中存储有用的指令来完成您需要在程序中发生的事情,例如执行操作或返回值。通过调用您的函数,您可以执行配方中包含的步骤。每次调用该函数时都可以这样做,而无需一次又一次地重写配方。

这是声明函数然后在 JavaScript 重新调用它的标准方法:

// function declaration
function sayHiStranger() {
  return 'Hi, stranger!'
}

// call the function
sayHiStranger()

您还可以编写与函数表达式相同的函数,如下所示:

const sayHiStranger = function () {
  return 'Hi, stranger!'
}

JavaScript 箭头函数始终是表达式。以下是使用粗箭头符号重写上述函数的方法:

const sayHiStranger = () => 'Hi, stranger'

这样做的好处包括:

  • 只有一行代码
  • 没有function关键字
  • 没有return关键字
  • 并且没有画括号 {}

在 JavaScript 中,函数是“一等公民”。您可以将函数存储在变量中,将它们作为参数传递给其他函数,并将它们作为值从其他函数返回。您可以使用 JavaScript 箭头函数完成所有这些操作。

无括号语法

在上面的例子中,函数没有参数。()在这种情况下,您必须在粗箭头 ( =>) 符号之前添加一组空括号。当您有多个参数时也是如此:

const ge.NETflixSeries = (seriesName, releaseDate) => `The ${seriesName} series was released in ${releaseDate}`
// call the function
console.log(getNetflixSeries('Bridgerton', '2020') )
// output: The Bridgerton series was released in 2020

但是,只需一个参数,您就可以继续省略括号(您不必这样做,但可以):

const favoriteSeries = seriesName => seriesName === "Bridgerton" ? "Let's watch it" : "Let's go out"
// call the function
console.log(favoriteSeries("Bridgerton"))
// output: "Let's watch it"

不过要小心。例如,如果您决定使用默认参数,则必须将其包装在括号内:

// with parentheses: correct
const bestNetflixSeries = (seriesName = "Bridgerton") => `${seriesName} is the best`
// outputs: "Bridgerton is the best"
console.log(bestNetflixSeries())

// no parentheses: error
const bestNetflixSeries = seriesName = "Bridgerton" => `${seriesName} is the best`
// Uncaught SyntaxError: invalid arrow-function arguments (parentheses around the arrow-function may help)

仅仅因为你可以,并不意味着你应该。Kyle Simpson(以You Don't Know JS成名)夹杂着一点轻松、善意的讽刺,将他对省略括号的想法写进了这个流程图。

隐式返回

当函数体中只有一个表达式时,就可以使用 ES6 箭头的语法更加简洁。您可以将所有内容保持在一行,删除花括号,并取消return关键字。

您刚刚在上面的示例中看到了这些漂亮的单行代码是如何工作的。这里还有一个例子,只是为了很好的衡量。该orderByLikes()函数执行它在罐头上所说的:也就是说,它返回一个按最高点赞数排序的 Netflix 系列对象数组:

// using the JS sort() function to sort the titles in descending order 
// according to the number of likes (more likes at the top, fewer at the bottom
const orderByLikes = netflixSeries.sort( (a, b) => b.likes - a.likes )

// call the function 
// output:the titles and the n. of likes in descending order
console.log(orderByLikes)

这很酷,但要注意代码的可读性——尤其是在使用单行和无括号的时候 ES6 箭头语法对一堆箭头函数进行排序时,就像在这个例子中一样:

const greeter = greeting => name => `${greeting}, ${name}!`

那里发生了什么事?尝试使用常规函数语法:

function greeter(greeting) {
  return function(name) {
    return `${greeting}, ${name}!` 
  }
} 

现在,您可以快速了解外部函数如何greeter具有参数greeting,并返回匿名函数。这个内部函数又调用了一个参数,并使用和name的值返回一个字符串。以下是调用函数的方法:greetingname

const myGreet = greeter('Good morning')
console.log( myGreet('Mary') )   

// output: 
"Good morning, Mary!" 

注意这些隐式返回错误

当您的 JavaScript 箭头函数包含多个语句时,您需要将所有语句括在花括号中并使用return关键字。

在下面的代码中,该函数构建了一个对象,其中包含一些 Netflix 系列的标题和摘要(Netflix 评论来自Rotten Tomatoes网站):

const seriesList = netflixSeries.map( series => {
  const contAIner = {}
  container.title = series.name 
  container.summary = series.summary

  // explicit return
  return container
} )

函数内部的箭头函数.map()由一系列语句发展而来,在语句结束时它返回一个对象。这使得在函数体周围使用花括号是不可避免的。

此外,当您使用花括号时,隐式返回不是一种选择。您必须使用return关键字。

如果您的函数使用隐式返回返回对象字面量,则需要将对象包装在圆括号内。不过这样做会导致错误,因为 JavaScript 引擎错误地将对象字面量的花括号解析为函数的花括号。正如您在上面刚刚注意到的,当您在箭头函数中使用花括号时,您不能省略 return 关键字。

前面代码的较短版本演示了这种语法:

// Uncaught SyntaxError: unexpected token: ':'
const seriesList = netflixSeries.map(series => { title: series.name });

// Works fine
const seriesList = netflixSeries.map(series => ({ title: series.name }));

你不能命名箭头函数

function在关键字和参数列表之间没有名称标识符的函数称为匿名函数。以下是常规匿名函数表达式的样子:

const anonymous = function() {
  return 'You can't identify me!' 
}

箭头函数都是匿名函数

const anonymousArrowFunc = () => 'You can't identify me!' 

name从 ES6 开始,变量和方法可以使用匿名函数的属性从其语法位置推断出匿名函数的名称。这使得在检查其值或报告错误时可以识别该函数。

使用以下方法检查anonymousArrowFunc:

console.log(anonymousArrowFunc.name)
// output: "anonymousArrowFunc"

请注意,此推断name属性仅在将匿名函数分配给变量时才存在,如上面的示例中所示。如果您使用匿名函数作为回调,您将失去这个有用的功能。这在下面的演示中得到了例证,其中方法内的匿名函数.setInterval()无法利用该name属性:

let counter = 5
let countDown = setInterval(() => {
  console.log(counter)
  counter--
  if (counter === 0) {
    console.log("I have no name!!")
    clearInterval(countDown)
  }
}, 1000)

这还不是全部。这个推断name的属性仍然不能作为一个正确的标识符,你可以使用它来从内部引用函数——例如递归、解除绑定事件等。

箭头函数的内在匿名性导致 Kyle Simpson 表达了他对它们的看法如下:

由于我认为匿名函数不是在您的程序中经常使用的好主意,因此我不喜欢使用=>箭头函数形式。——你不懂 JS

箭头函数如何处理this关键字

关于箭头函数要记住的最重要的事情是它们处理this关键字的方式。特别是,this箭头函数内的关键字不会反弹。

为了说明这意味着什么,请查看下面的演示:

[codepen_embed height=”300″ default_tab=”html,result” slug_hash=”qBqgBmR” user=”SitePoint”]在 CodePen 上的SitePoint ( @SitePoint )
箭头函数中查看 Pen JS。[/codepen_embed]

这是一个按钮。单击按钮会触发从 5 到 1 反向计数器,该计数器显示在按钮本身上。

<button class="start-btn">Start Counter</button>

...

const startBtn = document.querySelector(".start-btn");

startBtn.addEventListener('click', function() {
  this.classList.add('counting')
  let counter = 5;
  const timer = setInterval(() => {
    this.textContent = counter 
    counter -- 
    if(counter < 0) {
      this.textContent = 'THE END!'
      this.classList.remove('counting')
      clearInterval(timer)
    }
  }, 1000) 
})

注意方法中的事件处理程序.addEventListener()是一个普通的匿名函数表达式,而不是箭头函数。为什么?如果您this在函数内部登录,您会看到它引用了已附加侦听器的按钮元素,这正是程序按计划工作所期望的和需要的:

startBtn.addEventListener('click', function() {
  console.log(this)
  ...
})

这是 Firefox 开发者工具控制台中的样子:

JavaScript 中的箭头函数:如何使用 Fat & Concise 语法香草

 

但是,尝试用箭头函数替换常规函数,如下所示:

startBtn.addEventListener('click', () => {
  console.log(this)
  ...
})

现在,this不再引用该按钮。相反,它引用了Window对象:

JavaScript 中的箭头函数:如何使用 Fat & Concise 语法香草

 

这意味着,如果您想在this单击按钮后向按钮添加一个类,例如,您的代码将不起作用:

// change button's border's Appearance
this.classList.add('counting')

这是控制台中的错误消息:

JavaScript 中的箭头函数:如何使用 Fat & Concise 语法香草

 

在 JavaScript 中使用箭头函数时,this关键字的值不会反弹。它继承自父作用域(这称为词法作用域)。在这种特殊情况下,所讨论的箭头函数作为参数传递给startBtn.addEventListener()位于全局范围内的方法。因此,this函数处理程序内部也绑定到全局范围——即Window对象。

所以,如果要this在程序中引用开始按钮,正确的做法是使用常规函数,而不是箭头函数。

匿名箭头函数

在上面的演示中,接下来要注意的是.setInterval()方法中的代码。在这里,您也会找到一个匿名函数,但这次是箭头函数。为什么?

请注意,如果您使用常规函数,值this会是什么:

const timer = setInterval(function() {
  console.log(this)
  ...
}, 1000)

会是button元素吗?一点也不。这将是Window对象!

JavaScript 中的箭头函数:如何使用 Fat & Concise 语法香草

 

事实上,上下文已经改变,因为this现在在一个未绑定或全局函数中,该函数作为参数传递给.setInterval(). 因此,this关键字的值也发生了变化,因为它现在绑定到全局范围。

在这种情况下,一个常见的技巧是包含另一个变量来存储this关键字的值,以便它继续引用预期的元素——在这种情况下,button元素:

const that = this
const timer = setInterval(function() {
  console.log(that)
  ...
}, 1000)

您还可以使用.bind()来解决问题:

const timer = setInterval(function() {
  console.log(this)
  ...
}.bind(this), 1000)

使用箭头函数,问题就完全消失了。这this是使用箭头函数时的值:

const timer = setInterval( () => { 
  console.log(this)
  ...
}, 1000)
JavaScript 中的箭头函数:如何使用 Fat & Concise 语法香草

 

这一次,控制台记录了我们想要的按钮。其实程序是要改变按钮文字的,所以需要this引用button元素:

const timer = setInterval( () => { 
  console.log(this)
 // the button's text displays the timer value
  this.textContent = counter
}, 1000)

箭头函数没有自己的this上下文。他们继承了this父级的价值,正是因为这个特性,他们在上述情况下做出了很好的选择。

JavaScript 箭头函数并不总是适合这项工作的工具

箭头函数不仅仅是一种在 JavaScript 中编写函数的新奇方式。它们有自己的局限性,这意味着在某些情况下您不想使用它们。上一个演示中的点击处理程序就是一个很好的例子,但它不是唯一的。让我们再检查几个。

箭头函数作为对象方法

箭头函数不能很好地作为对象上的方法。这是一个例子。

考虑这个netflixSeries对象,它有一些属性和几个方法。调用console.log(netflixSeries.getLikes())应该打印一条带有当前点赞数的消息,调用console.log(netflixSeries.addLike())应该将点赞数加一,然后在控制台上打印新值和感谢消息:

const netflixSeries = {
  title: 'After Life', 
  firstRealease: 2019,
  likes: 5,
  getLikes: () => `${this.title} has ${this.likes} likes`,
  addLike: () => {  
    this.likes++
    return `Thank you for liking ${this.title}, which now has ${this.likes} likes`
  } 
}

相反,调用该.getLikes()方法返回“undefined has NaN likes”,调用该.addLike()方法返回“Thank you for like like undefined, which now has NaN likes”。所以,this.title并this.likes不能分别引用对象的属性title和likes。

再一次,问题在于箭头函数的词法范围。对象的this内部方法是引用父级的作用域,在这种情况下是Window对象,而不是父级本身——也就是说,不是netflixSeries对象。

当然,解决方案是使用常规函数:

const netflixSeries = {
  title: 'After Life', 
  firstRealease: 2019,
  likes: 5,
  getLikes() {
    return `${this.title} has ${this.likes} likes`
  },
  addLike() { 
    this.likes++
    return `Thank you for liking ${this.title}, which now has ${this.likes} likes`
  } 
}

// call the methods 
console.log(netflixSeries.getLikes())
console.log(netflixSeries.addLike())

// output: 
After Life has 5 likes
Thank you for liking After Life, which now has 6 likes

第三方库的箭头函数

另一个需要注意的问题是第三方库通常会绑定方法调用,以便this值指向有用的东西。

例如,在 jQuery 事件处理程序中,this您可以访问处理程序绑定到的 DOM 元素:

$('body').on('click', function() {
  console.log(this)
})
// <body>

但是如果我们使用箭头函数——正如我们所见,它没有自己的this上下文——我们会得到意想不到的结果:

$('body').on('click', () =>{
  console.log(this)
})
// Window

这是使用Vue的另一个示例:

new Vue({
  el: app,
  data: {
    message: 'Hello, World!'
  },
  created: function() {
    console.log(this.message);
  }
})
// Hello, World!

在created钩子内部,this绑定到 Vue 实例,所以“Hello, World!” 显示信息。

但是,如果我们使用箭头函数,this它将指向没有message属性的父作用域:

new Vue({
  el: app,
  data: {
    message: 'Hello, World!'
  },
  created: function() {
    console.log(this.message);
  }
})
// undefined

箭头函数没有arguments对象

有时,您可能需要创建一个参数数量不定的函数。例如,假设您要创建一个函数,按偏好排序列出您最喜欢的 Netflix 连续剧。但是,您还不知道要包含多少个系列。JavaScript 使arguments对象可用。这是一个类似数组的对象(不是完整的数组),它存储调用时传递给函数的值。

尝试使用箭头函数实现此功能:

const listYourFavNetflixSeries = () => {
  // we need to turn the arguments into a real array 
  // so we can use .map()
  const favSeries = Array.from(arguments) 
  return favSeries.map( (series, i) => {
    return `${series} is my #${i +1} favorite Netflix series`  
  } )
  console.log(arguments)
}

console.log(listYourFavNetflixSeries('Bridgerton', 'Ozark', 'After Life')) 

当您调用该函数时,您将收到以下错误消息:Uncaught ReferenceError: arguments is not defined. 这意味着该arguments对象在箭头函数中不可用。事实上,用常规函数替换箭头函数就可以了:

const listYourFavNetflixSeries = function() {
   const favSeries = Array.from(arguments) 
   return favSeries.map( (series, i) => {
     return `${series} is my #${i +1} favorite Netflix series`  
   } )
   console.log(arguments)
 }
console.log(listYourFavNetflixSeries('Bridgerton', 'Ozark', 'After Life'))

// output: 
["Bridgerton is my #1 favorite Netflix series",  "Ozark is my #2 favorite Netflix series",  "After Life is my #3 favorite Netflix series"]

因此,如果您需要该arguments对象,则不能使用箭头功能。

但是,如果您真的想使用箭头函数来复制相同的功能怎么办?您可以做的一件事是使用ES6 剩余参数( ...)。以下是重写函数的方法:

const listYourFavNetflixSeries = (...seriesList) => {
   return seriesList.map( (series, i) => {
     return `${series} is my #${i +1} favorite Netflix series`
   } )
 }

结论

通过使用箭头函数,您可以编写带有隐式返回的简洁单行语句,并且最终忘记旧时的技巧来解决thisJavaScript 中关键字的绑定问题。箭头函数也适用于数组方法,如.map(), .sort(), .forEach(),.filter()和.reduce()。但请记住:箭头函数不会取代常规的 JavaScript 函数。请记住,仅当它们是适合工作的工具时才使用 JavaScript 箭头函数。

如果本文对你有帮助,别忘记给我个3连 ,点赞,转发,评论,,咱们下期见。

收藏 等于白嫖,点赞才是真情。

亲爱的小伙伴们,有需要JAVA面试文档资料请点赞+转发,关注我后,私信我333就可以领取免费资料哦



Tags:JavaScript   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
JavaScript的异步编程常见模式
在JavaScript中,异步编程是一种处理长时间运行操作(如网络请求或I/O操作)的常见方式。它允许程序在等待这些操作完成时继续执行其他任务,从而提高应用程序的响应性和性能。JavaS...【详细内容】
2024-04-12  Search: JavaScript  点击:(6)  评论:(0)  加入收藏
17 个你需要知道的 JavaScript 优化技巧
你可能一直在使用JavaScript搞开发,但很多时候你可能对它提供的最新功能并不感冒,尽管这些功能在无需编写额外代码的情况下就可以解决你的问题。作为前端开发人员,我们必须了解...【详细内容】
2024-04-03  Search: JavaScript  点击:(6)  评论:(0)  加入收藏
你不可不知的 15 个 JavaScript 小贴士
在掌握如何编写JavaScript代码之后,那么就进阶到实践&mdash;&mdash;如何真正地解决问题。我们需要更改JS代码使其更简单、更易于阅读,因为这样的程序更易于团队成员之间紧密协...【详细内容】
2024-03-21  Search: JavaScript  点击:(29)  评论:(0)  加入收藏
构建一个通用灵活的JavaScript插件系统?看完你也会!
在软件开发中,插件系统为应用程序提供了巨大的灵活性和可扩展性。它们允许开发者在不修改核心代码的情况下扩展和定制应用程序的功能。本文将详细介绍如何构建一个灵活的Java...【详细内容】
2024-03-20  Search: JavaScript  点击:(23)  评论:(0)  加入收藏
对JavaScript代码压缩有什么好处?
对JavaScript代码进行压缩主要带来以下好处: 减小文件大小:通过移除代码中的空白符、换行符、注释,以及缩短变量名等方式,可以显著减小JavaScript文件的大小。这有助于减少网页...【详细内容】
2024-03-13  Search: JavaScript  点击:(5)  评论:(0)  加入收藏
跨端轻量JavaScript引擎的实现与探索
一、JavaScript 1.JavaScript语言JavaScript是ECMAScript的实现,由ECMA 39(欧洲计算机制造商协会39号技术委员会)负责制定ECMAScript标准。ECMAScript发展史: 2.JavaScript...【详细内容】
2024-03-12  Search: JavaScript  点击:(6)  评论:(0)  加入收藏
面向AI工程的五大JavaScript工具
令许多人惊讶的是,一向在Web开发领域中大放异彩的JavaScript在开发使用大语言模型(LLM)的应用程序方面同样大有价值。我们在本文中将介绍面向AI工程的五大工具,并为希望将LLM...【详细内容】
2024-02-06  Search: JavaScript  点击:(55)  评论:(0)  加入收藏
18个JavaScript技巧:编写简洁高效的代码
本文翻译自 18 JavaScript Tips : You Should Know for Clean and Efficient Code,作者:Shefali, 略有删改。在这篇文章中,我将分享18个JavaScript技巧,以及一些你应该知道的示例...【详细内容】
2024-01-30  Search: JavaScript  点击:(76)  评论:(0)  加入收藏
使用 JavaScript 清理我的 200GB iCloud,有了一个意外发现!
本文作者在综合成本因素之下,决定用 Java 脚本来清理一下自己的 iCloud,结果却有了一个意外发现,即在 iCloud 中上传同一个视频和删除此视频之后,iCloud 的空间并不一致,这到底是...【详细内容】
2024-01-11  Search: JavaScript  点击:(106)  评论:(0)  加入收藏
JavaScript前端框架2024年展望
Angular、Next.js、React和Solid的维护者和创作者们展望2024年,分享了他们计划中的改进。译自2024 Predictions by JavaScript Frontend Framework Maintainers,作者 Loraine...【详细内容】
2024-01-05  Search: JavaScript  点击:(96)  评论:(0)  加入收藏
▌简易百科推荐
JavaScript的异步编程常见模式
在JavaScript中,异步编程是一种处理长时间运行操作(如网络请求或I/O操作)的常见方式。它允许程序在等待这些操作完成时继续执行其他任务,从而提高应用程序的响应性和性能。JavaS...【详细内容】
2024-04-12  靳国梁    Tags:JavaScript   点击:(6)  评论:(0)  加入收藏
17 个你需要知道的 JavaScript 优化技巧
你可能一直在使用JavaScript搞开发,但很多时候你可能对它提供的最新功能并不感冒,尽管这些功能在无需编写额外代码的情况下就可以解决你的问题。作为前端开发人员,我们必须了解...【详细内容】
2024-04-03  前端新世界  微信公众号  Tags:JavaScript   点击:(6)  评论:(0)  加入收藏
你不可不知的 15 个 JavaScript 小贴士
在掌握如何编写JavaScript代码之后,那么就进阶到实践&mdash;&mdash;如何真正地解决问题。我们需要更改JS代码使其更简单、更易于阅读,因为这样的程序更易于团队成员之间紧密协...【详细内容】
2024-03-21  前端新世界  微信公众号  Tags:JavaScript   点击:(29)  评论:(0)  加入收藏
又出新JS运行时了!JS运行时大盘点
Node.js是基于Google V8引擎的JavaScript运行时,以非阻塞I/O和事件驱动架构为特色,实现全栈开发。它跨平台且拥有丰富的生态系统,但也面临安全性、TypeScript支持和性能等挑战...【详细内容】
2024-03-21  前端充电宝  微信公众号  Tags:JS   点击:(28)  评论:(0)  加入收藏
构建一个通用灵活的JavaScript插件系统?看完你也会!
在软件开发中,插件系统为应用程序提供了巨大的灵活性和可扩展性。它们允许开发者在不修改核心代码的情况下扩展和定制应用程序的功能。本文将详细介绍如何构建一个灵活的Java...【详细内容】
2024-03-20  前端历险记  微信公众号  Tags:JavaScript   点击:(23)  评论:(0)  加入收藏
对JavaScript代码压缩有什么好处?
对JavaScript代码进行压缩主要带来以下好处: 减小文件大小:通过移除代码中的空白符、换行符、注释,以及缩短变量名等方式,可以显著减小JavaScript文件的大小。这有助于减少网页...【详细内容】
2024-03-13  WangLiwen    Tags:JavaScript   点击:(5)  评论:(0)  加入收藏
跨端轻量JavaScript引擎的实现与探索
一、JavaScript 1.JavaScript语言JavaScript是ECMAScript的实现,由ECMA 39(欧洲计算机制造商协会39号技术委员会)负责制定ECMAScript标准。ECMAScript发展史: 2.JavaScript...【详细内容】
2024-03-12  京东云开发者    Tags:JavaScript   点击:(6)  评论:(0)  加入收藏
面向AI工程的五大JavaScript工具
令许多人惊讶的是,一向在Web开发领域中大放异彩的JavaScript在开发使用大语言模型(LLM)的应用程序方面同样大有价值。我们在本文中将介绍面向AI工程的五大工具,并为希望将LLM...【详细内容】
2024-02-06    51CTO  Tags:JavaScript   点击:(55)  评论:(0)  加入收藏
JS小知识,使用这6个小技巧,避免过多的使用 if 语句
最近在重构我的代码时,我注意到早期的代码使用了太多的 if 语句,达到了我以前从未见过的程度。这就是为什么我认为分享这些可以帮助我们避免使用过多 if 语句的简单技巧很重要...【详细内容】
2024-01-30  前端达人  今日头条  Tags:JS   点击:(60)  评论:(0)  加入收藏
18个JavaScript技巧:编写简洁高效的代码
本文翻译自 18 JavaScript Tips : You Should Know for Clean and Efficient Code,作者:Shefali, 略有删改。在这篇文章中,我将分享18个JavaScript技巧,以及一些你应该知道的示例...【详细内容】
2024-01-30  南城大前端  微信公众号  Tags:JavaScript   点击:(76)  评论:(0)  加入收藏
站内最新
站内热门
站内头条