Get to know MDN better
此页面由社区从英文翻译而来。了解更多并加入 MDN Web Docs 社区。
箭头函数表达式的语法比传统的函数表达式更简洁,但在语义上有一些差异,在用法上也有一些限制:
参数部分支持剩余参数、默认参数和解构,并且始终需要使用括号:
箭头函数可以是 async 的,方法是在表达式前加上 async 关键字。
让我们逐步将传统的匿名函数分解为最简单的箭头函数。每一步都是一个有效的箭头函数。
备注:传统函数表达式和箭头函数除了语法上的区别外,还有更多的不同。我们将在接下来的几个小节中详细介绍它们的行为差异。
在上面的示例中,参数周围的括号和函数体周围的大括号都可以省略。但是,只有在某些情况下才能省略。
只有当函数只有一个简单参数时,才能省略括号。如果函数有多个参数、无参数、默认参数、重组参数或其余参数,则需要在参数列表周围加上括号。
只有当函数直接返回表达式时,才可以省略大括号。如果函数体有额外的处理,则大括号是必需的,return 关键字也是必需的。箭头函数无法猜测函数体返回什么或何时返回。
箭头函数总是未命名的。如果箭头函数需要调用自身,请使用具名函数表达式。也可以将箭头函数赋值给一个变量,这样它就有了名字。
箭头函数既可以使用表达式体(expression body),也可以使用通常的块体(block body)。
在表达式体中,只需指定一个表达式,它将成为隐式返回值。在块体中,必须使用显式的 return 语句。
使用表达式体语法 (params) => { object: literal } 返回对象字面量时,不能按预期工作。
这是因为只有当箭头后面的标记不是左括号时,JavaScript 才会将箭头函数视为表达式体,因此括号({})内的代码会被解析为一系列语句,其中 foo 是标签,而不是对象字面量中的键。
要解决这个问题,可以用括号将对象字面量包装起来:
箭头函数表达式只能用于非方法函数,因为它们没有自己的 this。让我们看看将它们用作方法时会发生什么:
另外一个示例涉及到 Object.defineProperty():
由于类体具有 this 上下文,因此作为类字段的箭头函数会关闭类的 this 上下文,箭头函数体中的 this 将正确指向实例(对于静态字段来说是类本身)。但是,由于它是一个闭包,而不是函数本身的绑定,因此 this 的值不会根据执行上下文而改变。
箭头函数属性通常被称作“自动绑定方法”,因为它与普通方法的等价性相同:
备注:类字段是在实例(instance)上定义的,而不是在原型(prototype)上定义的,因此每次创建实例都会创建一个新的函数引用并分配一个新的闭包,这可能会导致比普通非绑定方法更多的内存使用。
出于类似原因,call()、apply() 和 bind() 方法在箭头函数上调用时不起作用,因为箭头函数是根据箭头函数定义的作用域来建立 this 的,而 this 值不会根据函数的调用方式而改变。
箭头函数没有自己的 arguments 对象。因此,在本例中,arguments 是对外层作用域参数的引用:
备注:在严格模式下不能声明名为 arguments 的变量,因此上面的代码会出现语法错误。这使得 arguments 的范围效应更容易理解。
在大多数情况下,使用剩余参数是比使用 arguments 对象更好的选择。
箭头函数不能用作构造函数,当使用 new 调用时会出错。它们也没有 prototype 属性。
箭头函数的主体中不能使用 yield 关键字(除非在箭头函数进一步嵌套的生成器函数中使用)。因此,箭头函数不能用作生成器。
箭头函数的参数和箭头之间不能换行。
为便于格式化,可在箭头后换行,或在函数体周围使用括号/花括号,如下图所示。也可以在参数之间换行。
虽然箭头函数中的箭头不是运算符,但与普通函数相比,箭头函数具有特殊的解析规则,与运算符优先级的交互方式不同。
由于 => 的优先级低于大多数运算符,因此需要使用括号来避免 callback || () 被解析为箭头函数的参数列表。
call()、apply() 和 bind()方法与传统函数一样按照预期工作,因为我们为每个方法建立了作用域:
对于箭头函数,由于我们的 add 函数基本上是在 globalThis(全局)作用域上创建的,因此它会假定 this 就是 globalThis。
使用箭头函数的最大好处可能是在使用 setTimeout() 和 EventTarget.prototype.addEventListener() 等方法时,这些方法通常需要某种闭包、call()、apply() 或 bind(),以确保函数在适当的作用域中执行。
对于传统的函数表达式,类似这样的代码并不能像预期的那样工作:
有了箭头函数,this 作用域更容易被保留:
| ECMAScript® 2027 Language Specification # sec-arrow-function-definitions |
启用 JavaScript 以查看此浏览器兼容性表。