Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/438.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么是;减少;及;“地图”;javascript中的闭包?_Javascript_Closures - Fatal编程技术网

为什么是;减少;及;“地图”;javascript中的闭包?

为什么是;减少;及;“地图”;javascript中的闭包?,javascript,closures,Javascript,Closures,我讨论过闭包,通常我把闭包看作是从另一个函数返回的函数,或者是在另一个函数中设置为全局的函数,这样新函数(返回函数或全局变量)就引用了创建它的初始封闭函数中的变量。最近,有人告诉我map或reduce函数形成闭包。这些函数返回一个或多个值,而不返回任何函数。我看不出当你只有一个回调时,这个方法是如何形成闭包的。事实上,MDN声明reduce函数返回一个“值”,map函数返回一个数组。那么关闭在哪里呢?有人能解释一下吗 如果局部变量存在于周围函数中,并且它们在闭包中使用,则在函数中定义的函数最终会

我讨论过闭包,通常我把闭包看作是从另一个函数返回的函数,或者是在另一个函数中设置为全局的函数,这样新函数(返回函数或全局变量)就引用了创建它的初始封闭函数中的变量。最近,有人告诉我map或reduce函数形成闭包。这些函数返回一个或多个值,而不返回任何函数。我看不出当你只有一个回调时,这个方法是如何形成闭包的。事实上,MDN声明reduce函数返回一个“值”,map函数返回一个数组。那么关闭在哪里呢?有人能解释一下吗

如果局部变量存在于周围函数中,并且它们在闭包中使用,则在函数中定义的函数最终会被定义为闭包

例如:

function boil(ocean) {
  var boiling = 100.0;

  return ocean.map(function(h2o) {
    return h2o.temp >= boiling ? 'vapour' : 'water';
  });
}
此处的
map
变量在主函数中定义,并在传递给
map
的函数中使用。回调函数使闭包行为更加明显,因为它们在不同的上下文中使用,但同样的原则适用。

闭包是回调函数。根据MDN:

A closure is the combination of a function and the lexical environment within which that function was declared.

所以当你写这样的东西时:

array.map(function(object) {
    // do something
});

您传入的函数成为闭包,因为它可以访问在调用array.map时出现的作用域。这就是JavaScript的工作原理。

感谢大家对这个问题的回答。通过这些和chrome调试器,我得出了结论。正如Alnitak所说,“
当它从外部范围访问变量时,这是一个闭包。仅仅拥有访问它们的能力是不够的。”这是我遗漏的一个要点。此外,您可以在通过闭包包含的chrome调试器变量的sources选项卡的scope部分中看到。因此,看看下面的示例,我们可以确切地看到闭包是什么:

routerAction: function () {
  var name = "alex"; 
  var alex = function(v){
    debugger;
    console.log("this is var ", name);
  }
    alex(); // if name was passed and then printed it would be local 
            // not a closure  
}
函数的作用域来自全局变量、局部变量和闭包变量。
当您将“name”作为参数传递到alex函数中时,它将成为局部变量,因此没有闭包。所以,如果我将它传递给alex,并且控制台记录了“v”,其中name是,则不会通过闭包引用任何变量。但是,由于名称是在函数alex的作用域之外定义的,然后在函数alex的作用域内使用,因此它的作用域是通过闭包确定的(这可以在chrome调试器的作用域部分中看到)。根据同样的逻辑,如果操作的数组(使用map或reduce)是在函数中定义的,则回调必须在回调中引用数组时形成闭包。如果参数只是通过参数引入的,那么没有一个变量是通过闭包访问的,它们都是局部变量

reduce
map
本身当然不会被任何人认为是“闭包”。它们接受的回调可能是。函数(AIUI)只有在使用词汇上可见(从更高级别的范围)且未在其自身范围内声明的变量时,才真正被视为闭包。因此,此结构本身不是闭包,它取决于创建它的环境?显然,如果在函数中执行此操作,它将形成一个闭包,但是独立语法array.map。。。没有作为其一部分的闭包。对的也许从理论的角度来看,你必须始终在某个顶级函数中,这样它在技术上总是会创建一个闭包。当它从外部范围访问变量时,它就是一个闭包。仅仅拥有访问它们的能力是不够的。这就是定义变得有点模糊的地方。我想,从技术上讲,如果回调函数没有捕获到局部变量,那么从定义上讲,它实际上不是一个闭包,但我曾经与之交谈过的每个人都将其称为闭包。基本上,当一个匿名函数被传递到另一个函数调用时,它几乎总是一个闭包。我想知道浏览器是否也为此进行了优化?也就是说,如果你从来没有使用过闭包范围变量,那么在你给出的例子中,它是否仍然保留着它们?这可能会对对象的垃圾收集产生有趣的影响。