javascript中的命名函数与未命名函数以及理解分配

Named vs unnamed functions in javascript and understanding allocation

本文关键字:函数 分配 未命名 javascript      更新时间:2023-09-26

当你查看 ECMAScript 6 规范时,我注意到了一些有趣的东西。

13 函数定义

语法

FunctionDeclaration : function Identifier ( FormalParameterListopt ) { FunctionBody }

FunctionExpression : function Identifieropt (FormalParameterListopt ) { FunctionBody }

这两种不同的声明类型进一步细分为以下语义定义:

生产FunctionExpression : function ( FormalParameterListopt ) { FunctionBody }评估如下:

返回创建新Function对象的结果,如 中指定 13.2 参数由FormalParameterListopt指定,主体由FunctionBody指定。通过LexicalEnvironment 将执行上下文作为范围运行。传入true作为 Strict标志(如果FunctionExpression包含在strict代码中) 或者如果其FunctionBodystrict代码。

和:

生产FunctionDeclaration : function Identifier ( FormalParameterListopt ) { FunctionBody }实例化如下 在声明绑定实例化 (10.5) 期间:

返回创建新Function对象的结果,如 中指定 13.2 参数由 FormalParameterListopt 指定,主体由 FunctionBody 指定。通过VariableEnvironment 将执行上下文作为范围运行。传入 true 作为Strict 标志,如果FunctionDeclaration包含在strict代码中,或者如果 它的FunctionBodystrict代码。

我是否正确地将其解释为声明

function foo(){};

定义为本质上在

"函数表"中声明,其中所有参数和变量在加载执行上下文时在堆栈上分配,而

function (){};

在解析要执行的

那一刻之前基本上不存在,其所有变量和范围都继承自有问题的本地执行上下文?

或者通俗地说,命名声明被预先分配,匿名声明在"运行时"分配?

这里的重要性在于命名函数和未命名函数之间的区别,而在于FunctionDeclarationFunctionExpression的区别。

函数声明采用以下形式:

function foo() {...}

请注意函数关键字的位置,其前面没有运算符。 此样式hoisted到当前上下文的顶部,在运行时可用,允许您执行以下操作:

foo();
function foo() {console.log("Foo was called");}

另一方面,如果在function关键字(如 =()前面放置任何类型的运算符,它就会变成函数表达式。 函数表达式在计算之前不可用。

foo(); // can't call it it here. `foo` exists due to hoisting, but it is `undefined`
var foo = function() {console.log("foo was called");}
foo();

"FunctionDeclaration"是一个语句,而"FunctionExpression"是一个表达式。

函数

声明语句和函数表达式之间的最大区别在于函数对象何时实例化,因此,此函数可以使用什么范围。

函数标识符("name")是语句的要求,对于表达式是可选的。

在这两种情况下,函数仅在调用时执行,但作为脚本静态分析的一部分进行解析 - 例如,如果函数表达式包含无效语句,则会引发解析错误,并且脚本不会执行。