Javascript var fn=function(){…}和var fn=function foo(){…}有什么不同吗?
当您将函数赋值给变量时,如果使用命名函数而不是匿名函数,会有什么不同吗。下面生成一个错误“foo()未定义” 有人能弄清楚这里发生了什么吗?因为它(Javascript var fn=function(){…}和var fn=function foo(){…}有什么不同吗?,javascript,Javascript,当您将函数赋值给变量时,如果使用命名函数而不是匿名函数,会有什么不同吗。下面生成一个错误“foo()未定义” 有人能弄清楚这里发生了什么吗?因为它(foo)没有定义;-) 在此上下文中,function是函数表达式(“FunctionExpression”)而不是函数语句(“FunctionDeclaration”)——语法中有两种不同的结果。只有函数语句表单[神奇地]将函数名赋值(并提升赋值)到相应的变量。即使使用函数表达式创建的函数也可以有一个名称,它恰好是可选的,但是与其他形式一样,没有隐
foo
)没有定义;-)
在此上下文中,function
是函数表达式(“FunctionExpression”)而不是函数语句(“FunctionDeclaration”)——语法中有两种不同的结果。只有函数语句表单[神奇地]将函数名赋值(并提升赋值)到相应的变量。即使使用函数表达式创建的函数也可以有一个名称,它恰好是可选的,但是与其他形式一样,没有隐式赋值
[编辑:显然这比我想象的更奇怪。在任何情况下,上述情况都适用于符合要求的浏览器。例如,这是不符合要求的,IE/JScript表现出不同的行为,这也是不符合要求的。根据语法规范,这两种情况都是不正确的实现。]
考虑以下内容,这将有望说明([更]符合性的实现)会理智地抛出异常的原因:
// `function` is just an expression here -- there is no good reason for it to
// cause an implicit side-effect. And, according to the specification, it will not.
(function foo () {}).name // "foo", at least in FF
foo // undefined
旁注:任何不是顶级语句或函数块内直接语句的函数生成都是函数表达式。以下行为在不同浏览器中都很奇怪:
foo() // works in IE (this should never work)
if (true) {
// this is an INVALID GRAMMAR production, although it is accepted in browsers,
// with different operational semantics
function foo () {
}
}
foo() // works in FF and IE (this should never work)
快乐编码
一次关于语法的小旅行。“规则”同样可以在那里找到,尽管我发现第5版是以最令人困惑的方式写的。(它错过了所有树木的森林…) 函数表达式的语法: FunctionDeclaration(我在上面称为function语句)和相关“链”的语法: 注意,“无效语法”没有语法规则。获取FunctionDeclaration的唯一方法是通过SourceElement,它仅在FunctionBody或程序内部有效(不包括其他块,如
if
)。“正常表达式”作为函数表达式受到限制,如下所示:
ExpressionStatement不能以大括号开头,因为这可能会使它与块不明确。另外,表达式语句不能以function关键字开头,因为这可能会使其与FunctionDeclaration不明确。
…以及规范中的一条贴切注释:
众所周知,ECMAScript的几个广泛使用的实现支持将FunctionDeclaration用作语句。但是,这些实现在应用于此类FunctionDeclaration的语义上存在显著的、不可调和的差异。由于这些不可调和的差异,将FunctionDeclaration用作语句会导致代码在实现之间无法可靠地移植
因为它(foo
)没有定义;-)
在此上下文中,function
是函数表达式(“FunctionExpression”)而不是函数语句(“FunctionDeclaration”)——语法中有两种不同的结果。只有函数语句表单[神奇地]将函数名赋值(并提升赋值)到相应的变量。即使使用函数表达式创建的函数也可以有一个名称,它恰好是可选的,但是与其他形式一样,没有隐式赋值
[编辑:显然这比我想象的更奇怪。在任何情况下,上述情况都适用于符合要求的浏览器。例如,这是不符合要求的,IE/JScript表现出不同的行为,这也是不符合要求的。根据语法规范,这两种情况都是不正确的实现。]
考虑以下内容,这将有望说明([更]符合性的实现)会理智地抛出异常的原因:
// `function` is just an expression here -- there is no good reason for it to
// cause an implicit side-effect. And, according to the specification, it will not.
(function foo () {}).name // "foo", at least in FF
foo // undefined
旁注:任何不是顶级语句或函数块内直接语句的函数生成都是函数表达式。以下行为在不同浏览器中都很奇怪:
foo() // works in IE (this should never work)
if (true) {
// this is an INVALID GRAMMAR production, although it is accepted in browsers,
// with different operational semantics
function foo () {
}
}
foo() // works in FF and IE (this should never work)
快乐编码
一次关于语法的小旅行。“规则”同样可以在那里找到,尽管我发现第5版是以最令人困惑的方式写的。(它错过了所有树木的森林…) 函数表达式的语法: FunctionDeclaration(我在上面称为function语句)和相关“链”的语法: 注意,“无效语法”没有语法规则。获取FunctionDeclaration的唯一方法是通过SourceElement,它仅在FunctionBody或程序内部有效(不包括其他块,如
if
)。“正常表达式”作为函数表达式受到限制,如下所示:
ExpressionStatement不能以大括号开头,因为这可能会使它与块不明确。另外,表达式语句不能以function关键字开头,因为这可能会使其与FunctionDeclaration不明确。
…以及规范中的一条贴切注释:
众所周知,ECMAScript的几个广泛使用的实现支持将FunctionDeclaration用作语句。但是,这些实现在应用于此类FunctionDeclaration的语义上存在显著的、不可调和的差异。由于这些不可调和的差异,将FunctionDeclaration用作语句会导致代码在实现之间无法可靠地移植
从技术上讲,
fn
是一个指向“foo”的函数指针,但在Javascript中并没有看到这一点。你应该写下:
function foo() {
/* ... */
}
foo();
<
function foo() {
/* ... */
}
foo();
var bar = function foo() {
document.write("Internally, Foo is " + typeof foo + "<br/>");
document.write("Internally, Bar is " + typeof bar + "<br/>");
};
document.write("Foo is " + typeof foo + "<br/>");
document.write("Bar is " + typeof bar + "<br/>");
bar();
Foo is undefined
Bar is function
Internally, Foo is function
Internally, Bar is function
var fn // declares a variable named fn
= function // initializes fn
foo // declares a name foo that is only visible within the function body.
(){
... // foo is visible here.
};
foo(); // foo is not defined here (except on IE 6 and earlier)
fn(); // works just fine.
function foo() {
};
var foo = function() {
};
function foo(){}
var bar = function foo(){}
if (true) {
function foo(){ }
}