JavaScript函数声明类型之间的区别

10

在阅读有关IronJS的资料时,我遇到了这篇文章:http://ironjs.wordpress.com/

其中包含以下内容:

*上下文敏感函数关键字

如果您不知道,这两个函数并不相同:

(function bar() { })  

function foo() { } 

如何找出它们的区别,我将留给读者作为一个练习。

有人可以解释一下这里的区别吗?


3
其中一个是函数声明,另一个是命名函数表达式。哪个是哪个留给读者自己去练习辨别吧。 ;) - Felix Kling
3
如果读者阅读 kangax 关于 NFE(命名函数表达式)的文章,他们应该会受益匪浅。http://kangax.github.com/nfe/ - Sean Vieira
@SeanVieira 谢谢你的链接,看起来是一篇不错的文章! - Gaz
4个回答

9
function foo() { }

创建一个函数。
(function foo(){ })

返回一个函数对象。您也可以使用:

(function foo(){ })(bar)

创建一个匿名函数。(注意,(bar) 表示在该函数内 this 指的是 bar 实例。)

查看这个 Stack Overflow 帖子获取更多信息。


1
你是指最终是立即执行函数还是自调用函数吗?虽然它会立即执行,但它仍然有一个名称,因此不是匿名的。(function(){ })(function(){ })(bar)才是匿名的。 - Felix Kling

6
我猜想两者的区别在于前者不可见于全局范围,而后者可在全局范围内使用。

иҝҷжҳҜжӯЈзЎ®зҡ„пјҢдҪҶйӮЈз§ҚеҪўејҸ并дёҚжҳҜеҫҲжңүз”ЁгҖӮжӣҙжңүз”Ёзҡ„жҳҜ(function(){}())жҲ–(function(){})()пјҢе®ғдҪҝеҮҪж•°еҜ№е…ЁеұҖиҢғеӣҙдёҚеҸҜи§ҒпјҢдҪҶз«ӢеҚіиҝҗиЎҢгҖӮ - timw4mail
2
但为什么呢?(我知道,但你可能应该解释一下。) - Felix Kling

4

补充@Amir的回答:

js>(function bar() {})(3)
js>bar
console:1       ReferenceError: bar is not defined
js>function foo() {}
js>foo
function foo() {
}

(在jsdb中执行的代码)

这些是命名函数,如果您没有在函数定义周围放置括号,则它们将成为局部作用域的一部分。function foo() {} 可以在稍后使用,但bar则不行。

第三个例子:

var x = function baz() {};

如果您运行以下命令:
js>var x = function baz() {}
js>baz
console:1       ReferenceError: baz is not defined

您会注意到,这与 (function baz(){})(3) 是类似的情况。

这种情况是

function foo() {}

这段代码很特别,Javascript解释器识别到它后会说:“哦,你想在本地作用域中定义一个名为'foo'的函数。”

至于即使未在本地作用域中定义,命名函数仍然有用的原因 - 命名函数 可以 在函数本身的作用域内访问:

js>var x = function fact(n) { return n*((n < 2) ? 1 : fact(n-1)); }
js>x(3)
6
js>fact
console:1       ReferenceError: fact is not defined

这里有一个名为“fact”的阶乘函数,但是“fact”这个名称只在函数本身的作用域内可见。


+1 的例子太多了。无论如何都应该避免使用命名函数表达式。如果我没记错的话,这会在旧版本的IE中引起一些奇怪的行为(即创建具有两个不同名称的相同函数的两个版本)。 - Felix Kling

2
第一个函数是一个带名称的匿名函数(耶)。该表达式求值为一个Function。第二个函数定义了一个带名称的函数并返回undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接