函数声明和函数表达式的区别
1.函数表达式的区分
函数声明必须带有标示符(Identifier)(就是大家常说的函数名称),而函数表达式则可以省略这个标示符
函数声明:
function 函数名称 (参数:可选){ 函数体 }
函数表达式:
function 函数名称(可选)(参数:可选){ 函数体 }
所以,可以看出,如果不声明函数名称,它肯定是表达式. 可如果声明了函数名称的话,如何判断是函数声明还是函数表达式呢?ECMAScript是通过上下文来区分的,如果function foo(){}是作为表达式的一部分的话,那它就是一个函数表达式,如果function foo(){}被包含在一个函数体内,或者位于程序的最顶部的话,那它就是一个函数声明。
总结:如何判断是函数表达式:
- 如果不声明函数名称,肯定是表达式
- 如果声明了函数名称,通过上下文区分。如果是作为表达式的一部分,那它就是一个函数表达式。
1.1 练习:指出下面每一个function foo(){}分别是函数声明还是函数表达式
function foo(){}
var bar = function foo(){};
new function bar(){};
(function(){
function bar(){}
})();
2.特殊的函数表达式——()分组操作符
还有一种函数表达式不太常见,就是被括号括住的(function foo(){}),他是表达式的原因是因为括号 ()是一个分组操作符,它的内部只能包含表达式,我们来看几个例子:
function foo(){} // 函数声明
(function foo(){}); // 函数表达式:包含在分组操作符内
try {
(var x = 5); // 分组操作符,只能包含表达式而不能包含语句:这里的var就是语句
} catch(err) {
// SyntaxError
}
2.1 思考:使用eval对JSON进行执行的时候,eval(‘(’ + json +’)’),JSON字符串为什么通常被包含在一个圆括号里?
3.解析过程的不同
解析器会率先读取函数声明,并使其在执行任何代码之前可用(可以访问);至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正被解释执行。——引自《JavaScript高级程序设计(第三版)》
练习题答案:
练习1.1
function foo(){} // 声明,因为它是程序的一部分
var bar = function foo(){}; // 表达式,因为它是赋值表达式的一部分
new function bar(){}; // 表达式,因为它是new表达式
(function(){
function bar(){} // 声明,因为它是函数体的一部分
})();
“`
练习2.1
在使用eval对JSON进行执行的时候,JSON字符串通常被包含在一个圆括号里:eval(‘(’ + json +
‘)’),这样做的原因就是因为分组操作符,也就是这对括号,会让解析器强制将JSON的花括号解析成表达式而不是代码块。
参考资料:https://www.cnblogs.com/TomXu/archive/2011/12/29/2290308.html