为什么我们不能立即调用函数声明?

时间:2019-10-18 02:35:39

标签: javascript function expression

为什么我们需要编写一个计算结果为函数类型的表达式以便立即调用函数?为什么我们不能只声明一个函数并立即调用它?

为什么

(function(){}()) or !function(){}()

为什么不

function(){}()

这与我想如何将它们放入内存有关,但是我很难找到一个完整的答案。

2 个答案:

答案 0 :(得分:7)

由于到达函数声明的最后},解释器将其前面的整个函数声明视为单条语句。如果将任何内容放在}之后,它将被解释为单独的独立未使用的表达式:

function foo() {
}('bar')

这将创建一个bar字符串,但解释器不对其执行任何操作-就像

function foo() {
}
'bar'

该字符串已声明,但未在任何地方使用。

如果您没有在括号中添加任何内容,则会抛出SyntaxError,因为解释器期望语句或表达式,但单独()都不是。

这有点像将东西放在if块之后。无论您在}块的if之后加上什么,以下内容都将被解释为完全独立的语句/表达式:

if (true) {
  // do something
}'foo';

在这里,就像函数声明示例一样,您正在创建一个包含foo的字符串,但是表达式未使用。

答案 1 :(得分:2)

原因在于处理ECMAScript代码的方式。

在初始化期间,首先处理函数声明,然后处理变量声明(此过程通常称为“提升”)。然后开始执行。

函数表达式在执行期间求值。

所以您不能立即执行函数声明,因为甚至变量都不存在,并且函数可能依赖的其他代码也没有执行。

考虑一些简单的事情:

last_added = max(
    (
        obj for obj in s3.list_objects_v2(Bucket='mybucket_name')['Contents']
        if not obj['Key'].endswith('.csv')
    ),
    key=lambda obj: obj['LastModified']
)

函数 foo randomNumber 之前(尽管代码顺序)存在,因此尝试立即执行该函数会引发引用错误。初始化完成后,将声明 foo randomNumber

为初始化 randomNumber 的RHS上的代码在初始化期间会分析语法错误,但直到执行阶段才会执行。

现在开始执行,函数表达式将执行并为 randomNumber 分配一个值,因此当调用 foo 时, randomNumber 存在并且具有任何内容对返回的RHS上的函数表达式进行赋值。