我记得采访腾讯实习生时,面试官问了我这样一个问题。

复制代码代码如下所示:

下面两个声明的区别是什么



函数(富){ };



var(=){ };



只知道这两个声明中的一个是函数声明的函数声明,而且差别不是很好,我最近看到了这方面的书籍,我想对它们做一个很好的总结。

在ECMAscript,有两个最常用的方法来创建函数对象,即使用一个函数表达式,或者使用一个函数声明。对此,ECMAscript规范指定的函数声明必须始终有一个标识符(标识符),即函数名和函数表达式,我们称之为,可略。

函数声明:

复制代码代码如下所示:

函数标识符(formalparameterlist选择functionbody){ }



函数声明解析过程如下:

1。创建一个新的函数对象,formalparameterlist指定参数,并functionbody指定函数体。当前运行环境的作用域链作为其范围。

2。以结果值(1)为当前变量对象创建一个名为标识符的属性。

函数表达式:

(函数表达式分为匿名函数和命名函数表达式)

复制代码代码如下所示:

函数标识符选择(formalparameterlist OPT){ functionbody } / /这里是有名函数表达式



命名函数表达式的解析过程如下所示:

1。创建一个新对象对象

2。将结果(1)添加到范围链的顶部

三.创建一个新的函数对象,formalparameterlist指定参数,并functionbody指定函数的主体。在当前运行的执行环境的作用域链作为其范围。

4。为结果(1)创建一个名为标识符的属性,其值为结果值(3)、只读值和非删除值。

5。从范围链中删除结果(1)

6。返回结果(3)

官方文件读起来很别扭。简单来说,脚本是根据上下文来区分这两个:如果函数(Foo){ }的一部分任务,它是一个函数表达式,如果函数(Foo){ }是包含在身体的一个函数,或在程序(顶部),它将解决它作为一个函数声明。显然,在标识符不作为的情况下,表达的只能是一种表达。

复制代码代码如下所示:

函数;因为它是程序的一部分



VaR的酒吧=功能(Foo){ }; / /表达,因为它是一个赋值表达式(assignmentexpression)部分



新功能(酒吧){ }; / /表达,因为它是一个新的表达(newexpression)部分



(函数(){())

功能(酒吧){ }; / /声明,因为它是身体的一部分的功能(functionbody)

});



还有一个例子:

复制代码代码如下所示:

(函数(富){ })



这也是函数表达式。它包含在一对括号中。在上下文中形成分组运算符。

复制代码代码如下所示:

函数(富){;函数声明



(函数({)});注意:它包含在包操作符中。



{试

(var x = 5);分组操作符只能包含表达式不能包含语句(这里是var语句)

}

捕捉(错误){

查询/ x = 5(由于VaR是一个语句,而不是表达式必须返回值的表达式求值,但声明不一定有回报价值评估-翻译

}



下面简要介绍函数声明和函数表达式之间的异同,声明和表达式的行为有非常微妙和重要的区别。

首先,一个函数声明的解析和评价之前,任何表达式进行分析和评估。即使是宣布在最后一行的源代码,它将在相同的范围内第一个表达式的第一评价。或很容易看到的一个例子。在下面的例子中,函数fn声明在警报。然而,当警报被执行,FN被定义:

复制代码代码如下所示:

警报(FN)(HelloWorld); / /输出!



函数FN(){

return'helloworld!;

}





简单地总结一下,差异在哪里

1。声明总是在作用域的开头解析。

2。表达式在遇到某个时间时执行。

函数声明的另一个重要特性是条件语句控制函数声明没有标准化,因此不同的环境可能会得到不同的结果:

复制代码代码如下所示:

不要这样做!

不同的浏览器将有不同的返回结果,



如果(真){

函数(){

return'first;

}

}

{其他

函数(){

return'second;

}

}

(富);





记住,这个案例使用函数表达式:

变量Foo;

如果(真){

函数(){

return'first;

};

}

{其他

函数(){

return'second;

};

}

(富);



那么,使用函数声明的实际规则是什么呢 U3000

functiondeclaration(一个函数声明)只能出现在程序(程序)或functionbody(函数体)。他们不能出现在块(block)({…}),例如,不能出现在的话,虽然,或陈述。因为块(块)只包含声明(声明)而不是sourceelement(源元)如functiondeclaration(函数声明)。

另一方面,如果我们仔细看看规则,我们会发现,让表达的唯一方式(表情)出现在块(block)是使它expressionstatement的一部分。然而,该规范明确规定,expressionstatement(语句)不能与关键字的功能。事实上,函数表达式不能同时出现在声明(声明)或块(块)。别忘了块(块)是由语句组成的。

由于上述限制,只要函数出现在块中,就像在上面的示例中一样,它们应该被看作是语法错误而不是函数声明或表达式。

U3000 U3000

那么我们应该什么时候使用函数声明或函数表达式呢函数声明只能出现在程序代码中,意味着只有在另一个函数的函数体或全球空间;他们的定义不能赋值给一个变量或属性,或作为一个参数出现在函数调用;下面的例子是函数声明允许foo的用法(酒吧()。)与当地的()是函数的声明语句的模式:

复制代码代码如下所示:

全局环境

函数(富){ }



函数本地(){

/本地环境

函数(bar){ }

回来吧;

}



当不能在语法中使用函数声明时,可以使用函数表达式。例如,将函数传递为参数,或者在对象的文字数量中定义函数:



复制代码代码如下所示:

这是一个匿名函数。

我打电话(函数(){()



以函数作为参数传递

});



这是一个名为函数的表达式。

我打电话(功能我(){)



以函数作为参数传递,函数名是我

});



其他功能

VaR MyObject = { {

表示:函数(){



是函数表达式

}

};



有限的知识,如果有错误,欢迎指正。