【问题标题】:Are these considered to be Javascript closures?这些是否被认为是 Javascript 闭包?
【发布时间】:2012-08-20 14:26:00
【问题描述】:

想在这里直截了当...所以我有 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? */ })();

【问题讨论】:

  • 您的问题中不需要那些 &lt;br/&gt; 标记。另外,()(); 绝对不是匿名函数的定义。
  • @Pointy 谢谢,总是有人告诉我 ()();是一个匿名函数。如果不是,它叫什么?
  • ()(); 没有特殊名称。第一个() 是分组运算符,它强制将内容视为表达式。这用于强制函数定义为表达式而不被视为语句。在这种情况下,第二个() 调用了该函数,但如果评估分组运算符的结果不是函数,则会出错。匿名函数只是一个没有名字的函数。

标签: javascript closures


【解决方案1】:

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

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

闭包的实际创建发生在运行时(这有点像重言式的陈述,因为计算机程序在运行之前不会发生任何事情),因为为了确定msg 的值,在Bar ,当Bar被执行时,解释器需要知道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”。但是,它会产生 3 次“hi 3”。如果只是将函数的定义添加到数组中,而使用外部函数中定义的变量,则创建了闭包,这怎么可能?

这是因为您需要 执行上下文 来定义闭包,这直到运行时才会发生。在执行数组中的函数时,i 的值是 3。在forEach 语句中,这就是执行上下文,这就是为什么输出总是使用 3。

【讨论】:

  • 你的意思是“......当 Foo 被执行时”。我认为。
  • 你是什么意思? Bar 的存在和它对 msg 的使用是导致关闭的原因。
【解决方案2】:

Bar 是闭包。

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

closure这个词最常见的意思是:在一个封闭函数中使用至少一个在封闭范围内定义的变量的函数。

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

【讨论】:

  • +1 直接回答...我希望我能投票给两个答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-22
  • 1970-01-01
  • 2014-04-16
  • 2011-08-11
  • 2021-05-04
  • 2023-04-03
  • 2020-01-03
相关资源
最近更新 更多