以下代码行之间有什么区别?
//Function declaration function foo() { return 5; } //Anonymous function expression var foo = function() { return 5; } //Named function expression var foo = function foo() { return 5; }
什么是命名/匿名函数表达式?
什么是声明的功能?
浏览器如何以不同方式处理这些结构?
对类似问题(var functionName = function(){} vs function functionName(){})的响应是不是完全正确?
它们实际上非常相似.你如何称呼它们完全相同.不同之处在于浏览器如何将它们加载到执行上下文中.
函数声明在执行任何代码之前加载.
函数表达式仅在解释器到达该行代码时加载.
因此,如果您尝试在加载之前调用函数表达式,则会出现错误!如果你调用一个函数声明,它将始终有效,因为在加载所有声明之前不能调用任何代码.
示例:函数表达式
alert(foo()); // ERROR! foo wasn't loaded yet var foo = function() { return 5; }
示例:功能声明
alert(foo()); // Alerts 5. Declarations are loaded before any code can run. function foo() { return 5; }
至于你问题的第二部分:
var foo = function foo() { return 5; }
和其他两个真的一样.只是这行代码用于导致safari中的错误,尽管它不再存在.
function foo() { ... }
由于函数提升,可以在定义之前和之后调用以这种方式声明的函数.
功能表达命名函数表达式
var foo = function bar() { ... }
匿名函数表达式
var foo = function() { ... }
foo()
只有在创建后才能调用.
(function() { ... }());结论
Crockford建议使用函数表达式,因为它清楚地表明它foo
是一个包含函数值的变量.嗯,就个人而言,我更喜欢使用声明,除非有表达的理由.
关于第3个定义:
var foo = function foo() { return 5; }
下面是一个示例,说明如何使用递归调用的可能性:
a = function b(i) { if (i>10) { return i; } else { return b(++i); } } console.log(a(5)); // outputs 11 console.log(a(10)); // outputs 11 console.log(a(11)); // outputs 11 console.log(a(15)); // outputs 15
编辑:更有趣的闭包示例:
a = function(c) { return function b(i){ if (i>c) { return i; } return b(++i); } } d = a(5); console.log(d(3)); // outputs 6 console.log(d(8)); // outputs 8
第一个语句取决于声明它的上下文.
如果它在全局上下文中声明,它将创建一个名为"foo"的隐含全局变量,它将是一个指向函数的变量.因此,函数调用"foo()"可以在你的javascript程序中的任何地方进行.
如果函数是在闭包中创建的,它将创建一个名为"foo"的隐含局部变量,然后您可以使用"foo()"来调用闭包内的函数.
编辑:
我还应该说函数语句(第一个)在函数表达式之前被解析(另外2个).这意味着如果您在脚本底部声明了该功能,您仍然可以在顶部使用它.函数表达式仅在执行代码命中时才会得到评估.
结束编辑
陈述2和3几乎相同.同样,如果在全局上下文中使用它们将创建全局变量,并且如果在闭包内使用它将创建局部变量.但值得注意的是语句3将忽略函数名称,所以你可以调用函数.因此
var foo = function foo() { return 5; }
是相同的
var foo = function fooYou() { return 5; }