这些被认为是Javascript闭包吗?

Pri*_*ERO 6 javascript closures

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

下面的函数创建一个闭包.

function Foo(message){
    var msg = message;

    return function Bar(){ 
        this.talk = function(){alert(msg); }
    }
};
Run Code Online (Sandbox Code Playgroud)

问:关闭哪个功能,Foo或者Bar
我总是认为闭包是Foo因为它会在结束时关闭Bar一次Bar.

下一个...

以下是匿名函数的定义:

()();
Run Code Online (Sandbox Code Playgroud)

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

(function(){ /* <-- Is this function also a closure? */ })();
Run Code Online (Sandbox Code Playgroud)

hvg*_*des 4

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

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

闭包的实际创建发生在运行时(这有点同义反复,因为计算机程序在运行之前不会发生任何事情),因为为了确定msg, in的值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')
Run Code Online (Sandbox Code Playgroud)

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

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