这些是否被认为是JavaScript闭包?

6

希望能澄清一下...我有两个问题。

下面的函数创建了一个闭包。

function Foo(message){
    var msg = message;

    return function Bar(){ 
        this.talk = function(){alert(msg); }
    }
};

问题:FooBar中哪一部分是闭包函数?

我一直以为闭包函数是Foo,因为它在Bar返回后关闭了Bar

接下来...

以下是匿名函数的定义:

()();

Q:这个匿名函数内的内部函数也是闭包吗?

(function(){ /* <-- Is this function also a closure? */ })();

你的问题中不需要那些<br/>标签。而且,()();绝对不是匿名函数的定义。 - Pointy
@Pointy 谢谢,我一直被告知()();是一个匿名函数。如果不是,它叫什么? - Prisoner ZERO
1
()(); 没有特殊的名称。第一个 () 是分组运算符,强制内容被视为表达式。这用于将函数定义强制为表达式而不是语句。第二个 () 在这种情况下调用函数,但如果评估分组运算符的结果不是函数,则会出错。匿名函数就是没有名称的函数。 - Felix Kling
2个回答

4
你需要使用基本原则。JavaScript使用词法作用域。这意味着执行上下文的作用域由代码如何定义(词法)确定。
我会说函数Bar的定义是导致闭包被创建的原因,因为msg在函数中“封闭”。实际上,在运行时才会创建闭包,因为为了在Bar执行时确定msg的值,解释器需要知道Foo执行时变量的值,以此类推。
我将为你的问题提供两个答案。学究式的回答是:单独的函数都不是闭包。定义在函数内的变量与函数运行时的执行上下文共同定义了闭包。通常的回答是:任何关闭变量的函数都是闭包(在你的例子中是Bar)。
考虑每个人在使用JavaScript时遇到的问题。
function A(x) {
   var y = x, fs = [];

   for (var i = 0; i < 3; i++) {
       fs.push(function(){
         console.log (i + " " + x);
       })
   }

   fs.forEach(function(g){g()})  
}

A('hi')

大多数人会认为这会产生输出'hi 1',然后是'hi 2',最后是'hi 3'。然而,它会产生三次'hi 3'的输出。如果仅仅是将函数定义添加到数组中,同时使用外部函数定义的变量来创建闭包,那么这是怎么回事呢?
这是因为需要执行上下文来定义闭包,而这只有在运行时才会发生。在数组中的函数执行时,i的值为3。在forEach语句中,这就是执行上下文,这就是为什么输出总是使用3的原因。

你的意思是当执行Foo时,我想是这样。 - Pointy
1
你是什么意思?Bar的存在以及它对msg的使用是导致闭包的原因。 - hvgotcodes

1

Bar 是闭包。

我们说 Bar 在其环境中封闭了变量msg

大多数情况下,闭包的意思是:一个函数使用至少一个在封闭作用域内定义的变量,在封闭函数内部。

回答您的第二个问题:(function(){ ... })() 就像它看起来的那样:一个匿名函数,而不是两个。除非它嵌套在另一个函数内部,否则通常不会称之为闭包。然而,嵌套在该匿名函数内部的函数可以是闭包(并且通常是这样)。


+1 对于直接的答案...我希望我能投两个答案。 - Prisoner ZERO

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