在 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)
据我了解就足够了。
有没有人知道何时以及为什么需要将命名函数分配给变量?
最佳答案
这里确实有两个不同的问题:
- 定义或表达函数的不同方式有何区别?
- 为什么
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
- 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 answer至 Why 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/