在Javascript中,何时需要将命名函数分配给变量?
在Babel JS()的在线回复中,当我键入时:在Javascript中,何时需要将命名函数分配给变量?,javascript,ecmascript-6,Javascript,Ecmascript 6,在Babel JS()的在线回复中,当我键入时: 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)就足够了 是否有人知道何时以及为什么有必要为变量指定一个名为的函数 function a(x) { } var a = function
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)
就足够了
是否有人知道何时以及为什么有必要为变量指定一个名为的函数
function a(x) { }
var a = function a(x) { }
然后,函数被提升到封闭范围的顶部,a
在整个范围内的解析时间立即可用
然而,当你写作时:
function a(x) { }
var a = function a(x) { }
然后var a
将不会在封闭范围内定义值,直到实际执行这一行
但是,在该函数中,不同的a
将作为函数本身的局部范围引用存在
通过使用
let a=function…
construct Babel更符合后一种形式,确保a
在运行时分配给(命名)函数表达式,而不是使用解析时函数声明。这里有两个不同的问题:
让a=(x)=>x+1
以这种方式传输问题1 让我们看一下您提到的三个备选方案: 函数声明:
function a(x) { ... }
var a = function (x) { ... }
var a = function a(x) { ... }
从语法上讲,它们必须始终以函数
()开头。它们在解析时被提升,并在本地范围内创建一个命名函数
(匿名)函数表达式:
function a(x) { ... }
var a = function (x) { ... }
var a = function a(x) { ... }
var a
本身将在解析时被提升,但它将未定义
,直到该行在运行时执行为止
命名函数表达式:
function a(x) { ... }
var a = function (x) { ... }
var a = function a(x) { ... }
虽然语法使它看起来像是对函数声明的赋值,但实际上它只是一个带名称的函数表达式。我觉得这很混乱,但这就是语法
最大的区别在于函数声明和函数表达式之间。通过声明,您可以执行以下操作:
a(1);
function a(x) { return x + 1; }
尽管尝试使用函数表达式(命名或匿名)执行此操作将导致错误
问题2
(x)=>x+1
分配给具有let
的块作用域变量,因此我们应该期望a
在运行时执行这一行之后才会定义。这应该是函数表达式,而不是函数声明
最后,为什么让a=(x)=>x+1
传输到命名函数表达式而不是匿名函数表达式?有什么区别?正如Alnitak和其他人指出的那样:
- 函数名出现在调试器中,这可能会有所帮助
- 命名函数定义内的作用域具有对函数本身的引用。这允许递归和访问包含函数的属性
我发现处理这个问题的最佳方法是使用。这似乎是根据标准()进行的: AssignmentExpression[In,Yield]:LeftHandSideExpression[?Yield]=AssignmentExpression[?In,Yield] 1.如果LeftHandSideExpression既不是ObjectLiteral也不是ArrayLiteral,则
a。让lref作为计算LeftHandSideExpression的结果。
b。返回初始值(lref)。
c。让rref作为赋值表达式求值的结果。
d。设rval为GetValue(rref)。
e。如果LeftHandSideExpression的IsAnonymousFunctionDefinition(AssignmentExpression)和IsIdentifierRef均为true,则
I.将hasNameProperty设为HasOwnProperty(rval,“名称”)。
二,。ReturnIfAbrupt(hasNameProperty)。
III.如果hasNameProperty为false,执行SetFunctionName(rval,GetReferencedName(lref)) 因此,每当计算未命名函数表达式对命名标识符的赋值时,函数名应设置为标识符名 Babel遵循此过程,并生成兼容的ES5实现。
Chrome(v46.0.2490.71,V8引擎…)不遵循此过程,在这种情况下,
name
等于'
至于问题本身 在Javascript中,何时需要将命名函数分配给变量
答案是永远不要。由开发人员决定是否/何时使用命名函数。这一决定可以归结为对名称的特定需求(如“字符串化”函数时)或调试需求(更好的堆栈跟踪…。这不是必需的,但如果函数没有名称,在某些浏览器中,它不会在堆栈跟踪中显示为“函数a”。因此,命名函数有助于简化调试。否则它们将显示为“匿名函数”。@Shilly还有另一个区别-命名函数将其名称暴露到自己的作用域中。@Alnitak:错误。它仅向作用域公开其名称(并使用提升)