给出以下示例:
setTimeout(function name(){console.log(1)}, 1000) (callback)
name()
(回调)是否被视为函数声明或命名函数表达式?
我知道函数声明被提升而函数表达式没有,但因为它在参数的上下文中,你如何确定是否可以提升它?
我不相信它是函数声明和函数表达式之间区别的重复。
我问一个特定的用例,即命名回调函数是函数声明还是函数表达式。我不认为在该问题中提供的答案中涵盖了这个用例。
答案 0 :(得分:5)
一般来说,如果函数定义在表达式位置,那么它就是函数表达式。
何时表达位置"?当你不能在那里发表声明时。
参数是表达式(您无法将if
语句作为参数传递)因此function name() {...}
是您示例中的表达式。
因为它是一个函数表达式,所以可以省略名称。
现在您可能想知道以下内容:假设您知道5 + 5
是一个表达式,您可以将5 + 5
放入一行中
5 + 5;
似乎我们可以将表达放在我们想要的任何地方。那么JavaScript如何决定,给出
function name() {
//...
}
是函数声明还是函数表达式?
要回答这个问题,我们必须看一下代码的结构。在顶级,您拥有的是语句:
的列表<statement1>
<statement2>
<statement3>
...
There are various types of statements,if
语句就是一个例子。还有ExpressionStatement
的概念。顾名思义,它是一个由单个表达式组成的语句。这是允许您将5 + 5;
放入该语句列表中的规则。
但此解析规则受到限制。它不能以关键字function
(以及其他)开头。因此,当JavaScript遇到上述函数定义时,它不会被解析为函数表达式,因为它无法将其解析为ExpressionStatement
。剩下的唯一选择是将其解析为函数声明。
如果您对JavaScript程序的结构感到好奇,可以使用https://astexplorer.net(完全披露:我构建了这个网站)来查看流行的JavaScript解析器如何削减该程序。
例如,
setTimeout(function name(){console.log(1)}, 1000)
(你应该真正看看实时版本,因为将鼠标悬停在AST上会突出显示相应的源文本,这会让事情变得更容易理解)
答案 1 :(得分:1)
是的,这是一个表达方式。并且该函数可以通过其名称来调用。
试试这个:
setTimeout(function name(){
console.log(1);
console.log(name);
}, 1000)
虽然调用了一个停止条件,否则你将耗尽堆栈。递归咬......