// 千万不要这样做!
// 不同浏览器会有不同返回结果,
if (true) {
function foo() {
return 'first';
}
}
else {
function foo() {
return 'second';
}
}
foo();
// 记住,这种情况下要使用函数表达式:
var foo;
if (true) {
foo = function() {
return 'first';
};
}
else {
foo = function() {
return 'second';
};
}
foo();
那么,使用函数声明的实际规则到底是什么?
FunctionDeclaration(函数声明)只能出现在Program(程序)或FunctionBody(函数体)内。从句法上讲,它们 不能出现在Block(块)({ ... })中,例如不能出现在 if、while 或 for 语句中。因为 Block(块) 中只能包含Statement(语句), 而不能包含FunctionDeclaration(函数声明)这样的SourceElement(源元素)。
另一方面,仔细看一看产生规则也会发现,唯一可能让Expression(表达式)出现在Block(块)中情形,就是让它作为ExpressionStatement(表达式语句)的一部分。但是,规范明确规定了ExpressionStatement(表达式语句)不能以关键字function开头。而这实际上就是说,FunctionExpression(函数表达式)同样也不能出现在Statement(语句)或Block(块)中(别忘了Block(块)就是由Statement(语句)构成的)。
由于存在上述限制,只要函数出现在块中(像上面例子中那样),实际上就应该将其看作一个语法错误,而不是什么函数声明或表达式。
那么我们应该在什么时候使用函数声明或函数表达式呢?函数声明只能出现在“程序代码”中,意味着只能在其它函数体中或者全局空间;它们的定义不能不能赋值给一个变量或属性,或者作为一个参数传递出现在函数调用中;下面的例子是函数声明的允许的用法,foo(),bar()和local()都是通过函数声明模式声明:
复制代码 代码如下:
// 全局环境
function foo() {}
function local() {
// 局部环境
function bar() {}
return bar;
}
当你在语法上不能使用函数声明的时候,你就可以使用函数表达式。比如:传递一个函数作为参数或者在对象字面量中定义一个函数:
复制代码 代码如下:
// 这是一个匿名函数表达式
callMe(function () {
//传递一个函数作为参数
});
// 这是一个具名函数表达式
callMe(function me() {
// 传递一个函数作为参数,函数名为me
});
// 其他函数表达式
var myobject = {
say: function () {
// I am a function expression
}
};
学识有限,如有错误,欢迎指正。
您可能感兴趣的文章: