这些被认为是Javascript闭包吗?

时间:2012-08-20 14:26:01

标签: javascript closures

想在这里得到一些东西......所以我有2个问题

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

function Foo(message){
    var msg = message;

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

问:闭包是哪个功能,FooBar
我一直认为闭包是Foo,因为一旦Bar返回,它就会关闭Bar

下一步...

以下是匿名函数的定义:

()();

问:这个匿名函数中的内部函数是否也是一个闭包?

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

2 个答案:

答案 0 :(得分:4)

您需要在此处使用第一原则。 Javascript使用词法范围。这意味着执行上下文的范围取决于代码定义(词法)的方式。

我会说函数Bar定义导致创建闭包的原因,因为msg是“封闭的” “在功能中。

关闭的实际创建发生在运行时(这在某种程度上是重复的声明,因为计算机程序在运行之前不会发生任何事情),因为为了确定msg的值,在{ {1}},当执行Bar时,解释器需要在执行Bar时知道变量的值,依此类推。

我会给你的问题两个答案。迂腐的答案是:两个函数本身都不是闭包。它是函数中变量的定义,与函数运行时的执行上下文相结合,即定义闭包。常见的答案是:任何关闭变量的函数都是一个闭包(在你的情况下为Bar)。

考虑每个人在使用Javascript时遇到的问题。

Foo

大多数人会说这会产生输出'hi 1',然后是'hi 2',然后是'hi 3'。然而,它产生'喜3'3次。如果只是将函数的定义添加到数组中,同时使用外部函数中定义的变量,创建了闭包,这怎么可能呢?

这是因为您需要执行上下文来定义闭包,这在运行时才会发生。在执行数组中的函数时,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') 的值为i。在3语句中,这是执行上下文,这就是输出始终使用3的原因。

答案 1 :(得分:1)

Bar是关闭。

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

closure 这个词通常意味着:在封闭函数中使用至少一个在封闭范围内定义的变量的函数。

回答你的第二个问题:(function(){ ... })()就是它的样子:一个匿名函数,而不是两个。除非它嵌套在另一个函数中,否则通常不会将其称为闭包。但是,嵌套在匿名函数中的函数可以是闭包(通常是)。