Han*_*Sun 9 javascript ecmascript-6
在Babel JS的在线REPL(http://babeljs.io/repl/)中,当我输入时:
let a = (x) => x+1
Run Code Online (Sandbox Code Playgroud)
它将被转化为:
"use strict";
var a = function a(x) {
return x + 1;
};
Run Code Online (Sandbox Code Playgroud)
这var a = function a(x)看起来有点令我困惑,因为我理解其中任何一个var a = function(x)或function a(x)足够.
有没有人有关于何时以及为什么需要将命名函数分配给变量的想法?
这里有两个不同的问题:
let a = (x) => x + 1变换?为了回答(2)我们需要理解(1) - 已经在SO和其他地方广泛讨论过.让我们来看看你提到的三个选择:
功能声明:
function a(x) { ... }
Run Code Online (Sandbox Code Playgroud)
从语法上讲,这些必须始终以function(引用)开头.它们在分析时提升并在本地范围内创建命名函数.
(匿名)函数表达式:
var a = function (x) { ... }
Run Code Online (Sandbox Code Playgroud)
var a它本身将在解析时提升,但undefined直到此行在运行时执行.
命名函数表达式:
var a = function a(x) { ... }
Run Code Online (Sandbox Code Playgroud)
虽然语法使它看起来像是函数声明的赋值,但实际上它只是一个带有名称的函数表达式.我发现这令人困惑,但这就是语法.
最大的区别在于函数声明和函数表达式.通过声明,您可以:
a(1);
function a(x) { return x + 1; }
Run Code Online (Sandbox Code Playgroud)
虽然尝试使用函数表达式(命名或匿名)会导致错误.
它应该是直观清楚为什么let a = (x) => x + 1应该不被transpiled到函数声明.我们将箭头函数分配(x) => x + 1给一个块作用域的变量let,所以我们应该期望a直到在运行时执行该行之后才定义它.
那么,我们还有一个问题:为什么会被let a = (x) => x + 1转换为命名函数表达式而不是匿名函数表达式?有什么不同?正如Alnitak和其他人指出的那样:
所以命名函数表达式有一些很好的属性,匿名函数表达式没有.但实际上似乎对这里应该发生的事情存在分歧.据MDN称:
箭头功能始终是匿名的
"[从ES6开始]很多"匿名"函数表达式创建了带有名称的函数,这是各种现代JavaScript引擎在从上下文推断名称时非常聪明的事情......这在整个规范中散布着"
其他参考:
我发现掌握这个问题的最佳方法是使用Babel REPL.
如果你写:
function a(x) { }
Run Code Online (Sandbox Code Playgroud)
然后该函数被提升到封闭范围的顶部,并a在整个范围内的解析时立即变得可用。
然而,当你写:
var a = function a(x) { }
Run Code Online (Sandbox Code Playgroud)
then在实际执行该行之前,在封闭范围内var a不会有定义的值。
但是,在该函数内,将存在一个不同的 a函数作为对函数本身的本地范围引用。
通过使用let a = function ...构造 Babel 与后一种形式更加一致,确保a在运行时分配给(命名的)函数表达式,而不是使用解析时函数声明。
| 归档时间: |
|
| 查看次数: |
939 次 |
| 最近记录: |