javascript - 在 Javascript 中,什么时候需要将命名函数分配给变量?

标签 javascript ecmascript-6

在 Babel JS 的在线 REPL(http://babeljs.io/repl/)中,当我输入:

let a = (x) => x+1

它将被转译为:

"use strict";

var a = function a(x) {
  return x + 1;
};

这里的 var a = function a(x) 对我来说有点困惑,因为 var a = function(x)function a( x) 据我了解就足够了。

有没有人知道何时以及为什么需要将命名函数分配给变量?

最佳答案

这里确实有两个不同的问题:

  1. 定义或表达函数的不同方式有何区别?
  2. 为什么 let a = (x) => x + 1 以这种方式转译?

为了回答 (2),我们需要理解 (1)-- 这已在 SO 和其他地方进行了广泛讨论。


问题一

让我们来看看您提到的三种选择:

函数声明:

function a(x) { ... }

从语法上讲,这些必须总是function ( reference ) 开头。它们在解析时被提升并在本地范围内创建命名函数。

(匿名)函数表达式:

var a = function (x) { ... }

var a 本身将在解析时被提升,但在运行时执行此行之前它将是 undefined

命名函数表达式:

var a = function a(x) { ... }

尽管语法使它看起来像是对函数声明 的赋值,但这实际上只是一个带有名称的函数表达式。我觉得这令人困惑,但这就是语法。

最大的区别在于函数声明函数表达式。通过声明,您可以:

a(1);
function a(x) { return x + 1; }

尽管尝试使用函数表达式(命名匿名)会导致错误。


问题2

  1. Why does let a = (x) => x + 1 get transpiled this way?

我们将箭头函数 (x) => x + 1 分配给带有 let 的 block 范围变量,所以我们应该期望 a 直到该行在运行时执行后才被定义。这应该是一个函数表达式,而不是一个函数声明

最后,为什么 let a = (x) => x + 1 被转译成一个命名函数表达式而不是一个匿名函数表达式?有什么不同?正如 Alnitak 和其他人所指出的:

  • 函数名称出现在调试器中,这很有用。
  • 命名函数定义内的作用域引用了函数本身。这允许递归和访问包含函数的属性。

因此,命名函数表达式 具有一些匿名函数表达式 所没有的优良特性。但实际上似乎对这里应该发生的事情存在分歧。根据MDN :

Arrow functions are always anonymous

鉴于this answerWhy use named function expressions?说:

"[As of ES6] a lot of "anonymous" function expressions create functions with names, and this was predated by various modern JavaScript engines being quite smart about inferring names from context... This is strewn throughout the spec"

其他引用:

我发现解决这个问题的最佳方法是使用 Babel REPL .

关于javascript - 在 Javascript 中,什么时候需要将命名函数分配给变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33627048/

相关文章:

javascript - 使用 BackBone 查看 javascript 对象更改

javascript - 我可以使用 Python 和 Selenium 的正则表达式找到一个元素吗?

javascript - 发布 NPM 包时,我得到一个空对象,我的设置是 (ES6,Babel,Webpack,React,Redux,Sagas)

JavaScript : How to write Square bracket in array element

javascript - react 处理状态

javascript - Angular 不从工厂获取数据

javascript - 使用 JQuery/CSS 在页面上滑动 Div

javascript - "Uncaught Cannot extend unknown button type: copyHtml5"- 如何使用 `datatables.net-buttons-bs4`

javascript - 在 Node.js v 8.9.3 上,扩展类上的 Array.concat 方法会删除空值 - 为什么?

javascript - 如何滚动到一个元素?