你真的了解JavaScript里的箭头函数(Arrow Function)吗(一)?

我们将会学习箭头函数的全部知识点,向你展示如何使用ES6 arrow语法,以及如何避免使用箭头函数时易出现的错误点

前言

随着ECMAScript 2015(亦被称为ES6)的发布,Javascript箭头函数的时代也随之到来,由于它简洁的语法,以及对this关键字的灵活处理,箭头函数立马成为了开发者的心头之爱(吼吼吼,谁能不爱它呢?)

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

以前,我们通常是这样定义函数

// 函数声明(function declaration)
function sayHiStranger() {
  return 'Hi, stranger!'
}

// 调用函数(call the function)
sayHiStranger()

亦可用 函数表达式(function expression) 的语法,如下所示:

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

箭头函数通常为函数表达式,你可以使用转到运算符(fat narrow notation)方式重写上面函数

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

优点如下所示:

  • 只需一行代码
  • 没有function关键字
  • 没有return关键字
  • 没有大括号(curly braces)

在JavaScript里,函数(functions)一级公民(first-class citizens),你可以将函数存储在变量内,将它们以参数的形式传递给其他函数,也可以将它们作为函数的返回值。你现在能使用JavaScript的箭头函数做全部的事情。

无需括弧的语法

在上面的例子中,函数没有参数。你必须在箭头标志=>(fat arrow)前添加空括弧()。函数若有超过1个参数,也需要使用括弧

const getNetflixSeries = (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

只有一个参数,则你无需括弧(你没必要这么做,但你能这么做you don’t have to, but you can)

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"

需要注意的是,若这个参数有默认值default parameter,你必须使用括弧包裹它

// 有括弧:正确
const bestNetflixSeries = (seriesName = "Bridgerton") => `${seriesName} is the best`
// outputs: "Bridgerton is the best"
console.log(bestNetflixSeries())

// 没有括弧:报错
const bestNetflixSeries = seriesName = "Bridgerton" => `${seriesName} is the best`
// Uncaught SyntaxError: invalid arrow-function arguments (parentheses around the arrow-function may help)

隐性return(Implicit Return)

你可以使用下面的箭头函数,将数值按照降序的方式排列

const orderByLikes = netflixSeries.sort( (a, b) => b.likes - a.likes )

看起来很酷,但是需要注意代码的可读性—尤其当连续好几个箭头且无括弧的情况下,如下例所示:

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

这是神马?我们试图用普通的函数语法来表示它:

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

看到上面代码,你很快明白了,greeter 函数有1个参数greeting,返回值为匿名函数。内部函数有1个参数name,返回值为greetingname的字符串值,下面是你调用该函数的方式:

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

// output: 
"Good morning, Mary!" 

注意这些隐性return(Implicit Return)的错误

若箭头函数内的代码超过一行时,你需要用{}包裹它们,并使用return关键字,如下面代码所示:

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

  // explicit return(清晰return)
  return container
} )

若函数直接返回一个对象,此时你可以使用隐性return,但你必须使用()将返回的对象包裹。若不这样做,会造成错误,因为Javascript引擎会将对象的{}当作函数{}语法,造成解析错误。如下面代码所示:

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

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

我想你已经注意到了,如果在箭头函数内使用{},你不可避免地需要用到return关键字。

不能为箭头函数取名

function关键字和参数列表(parameter list)之间,若没有名称标记(name identifier),则为匿名函数(anonymous functions),如下例所示:

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

箭头函数都是匿名函数

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

ES6中,变量和方法可以使用匿名函数的name属性,推断匿名函数的名称,如下例所示:

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

注意:使用name进行推导,仅限于已将匿名函数赋值给一个变量,如上例所示。如果你在回调函数callbak内使用,那么你将无法使用这个特征。如下例所示:

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

setInterval() 方法内的箭头匿名函数,无法使用name属性获取到它

针对箭头函数本身的匿名特点,Kyle Simpson说道:

我不太赞成在代码内经常使用箭头函数,我不是=>箭头函数的粉丝
Since I don’t think anonymous functions are a good idea to use frequently in your programs, I’m not a fan of using the => arrow function form. — You Don’t Know JS

今天的课先到这里,我们将会在下节课继续,欢迎感兴趣的同学在评论区留言

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值