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


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

    前言

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

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

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

    // 函数声明(function declaration)
    function sayHiStranger() {
      return 'Hi, stranger!'
    }
    
    // 调用函数(call the function)
    sayHiStranger()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

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

    const sayHiStranger = function () {
      return 'Hi, stranger!'
    }
    
    • 1
    • 2
    • 3

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

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

    优点如下所示:

    • 只需一行代码
    • 没有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
    
    • 1
    • 2
    • 3
    • 4

    只有一个参数,则你无需括弧(你没必要这么做,但你能这么做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"
    
    • 1
    • 2
    • 3
    • 4

    需要注意的是,若这个参数有默认值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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    隐性return(Implicit Return)

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

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

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

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

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

    function greeter(greeting) {
      return function(name) {
        return `${greeting}, ${name}!` 
      }
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5

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

    const myGreet = greeter('Good morning')
    console.log( myGreet('Mary') )   
    
    // output: 
    "Good morning, Mary!" 
    
    • 1
    • 2
    • 3
    • 4
    • 5

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

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

    const seriesList = netflixSeries.map( series => {
      const container = {}
      container.title = series.name 
      container.summary = series.summary
    
      // explicit return(清晰return)
      return container
    } )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

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

    // Uncaught SyntaxError: unexpected token: ':'
    const seriesList = netflixSeries.map(series => { title: series.name });
    
    // Works fine
    const seriesList = netflixSeries.map(series => ({ title: series.name }));
    
    • 1
    • 2
    • 3
    • 4
    • 5

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

    不能为箭头函数取名

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

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

    箭头函数都是匿名函数

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

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

    console.log(anonymousArrowFunc.name)
    // output: "anonymousArrowFunc"
    
    • 1
    • 2

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

    let counter = 5
    let countDown = setInterval(() => {
      console.log(counter)
      counter--
      if (counter === 0) {
        console.log("I have no name!!")
        clearInterval(countDown)
      }
    }, 1000)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    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

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

  • 相关阅读:
    Android自定义View(下)
    bp神经网络的应用领域,BP神经网络能够做什么
    【专升本毕业设计报告】33台词网系统_测试方案_测试报告_测试用例_自动化测试_性能测试_缺陷报告
    如何区分汽车ECU的ABCD样?
    如何使用html、css制作一个期末作业网站【羽毛球体育运动主题html网页设计】
    【并发编程】AQS & ReentrantLock 底层实现原理
    Eureka的设计理念
    《DevOps 精要:业务视角》- 读书笔记(二)
    事件处理、事件修饰符(详细)
    Java.lang.Class类 getDeclaringClass()方法有什么功能呢?
  • 原文地址:https://blog.csdn.net/zwf193071/article/details/125414482