想在这里得到一些东西......所以我有2个问题
下面的函数会创建一个闭包。
function Foo(message){
var msg = message;
return function Bar(){
this.talk = function(){alert(msg); }
}
};
问:闭包是哪个功能,Foo
或Bar
?
我一直认为闭包是Foo
,因为一旦Bar
返回,它就会关闭Bar
。
下一步...
以下是匿名函数的定义:
()();
问:这个匿名函数中的内部函数是否也是一个闭包?
(function(){ /* <-- Is this function also a closure? */ })();
答案 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(){ ... })()
就是它的样子:一个匿名函数,而不是两个。除非它嵌套在另一个函数中,否则通常不会将其称为闭包。但是,嵌套在匿名函数中的函数可以是闭包(通常是)。