在javascript中命名vs未命名的函数并理解分配

时间:2016-04-23 18:36:35

标签: javascript ecmascript-6

当您查看ECMAScript 6 specification时,我注意到了一些有趣的事情。

  

13 功能定义

     

语法

     

FunctionDeclaration : function Identifier ( FormalParameterListopt ) { FunctionBody }

     

FunctionExpression : function Identifieropt (FormalParameterListopt ) { FunctionBody }

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

  

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

     

返回创建新Function对象的结果,如中所述   13.2,参数由FormalParameterListopt指定,正文由FunctionBody指定。通过LexicalEnvironment   将执行上下文作为Scope运行。通过true作为   如果Strict代码中包含FunctionExpression,则会strict标记   或者FunctionBodystrict代码。

  

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

     

返回创建新Function对象的结果,如中所述   13.2,参数由FormalParameterListopt指定,正文由FunctionBody指定。通过VariableEnvironment   将执行上下文作为Scope运行。传入true为Strict   如果FunctionDeclaration代码中包含strict或是否包含该标记   其FunctionBodystrict代码。

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

function foo(){};

被定义为基本上在“函数表”中声明,其中所有参数和变量在加载执行上下文时在堆栈上分配,而

function (){};

在解析执行之前基本上不存在,其所有变量和范围都是从有问题的本地执行上下文继承的?

或者用外行的术语来说,命名声明是预分配的,匿名声明是在“运行时”分配的。

2 个答案:

答案 0 :(得分:4)

此处的重要性是命名和未命名函数之间的区别,而是FunctionExpression vs 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(); ,它就会成为函数表达式。在评估函数表达式之前,函数表达式不可用。

io.Reader

答案 1 :(得分:3)

A" 功能声明"是一个声明,而一个" FunctionExpression "是,表达。

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

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

在这两种情况下,该函数仅在被调用时执行,但作为脚本静态分析的一部分进行解析 - 例如,如果函数表达式包含无效语句,则会抛出解析错误并且脚本赢了&#39 ; t执行。