想要在这里得到一些东西。。。所以我有两个问题
下面的函数创建一个闭包
function Foo(message){
var msg = message;
return function Bar(){
this.talk = function(){alert(msg); }
}
};
Q:闭包是Foo
还是Bar
我一直认为闭包是Foo
,因为一旦返回Bar
,它就会在Bar
上闭合。
下一步。。。
以下是匿名函数的定义:
()();
问:这个匿名函数中的内部函数也是闭包吗
(function(){ /* <-- Is this function also a closure? */ })();
这里需要使用第一性原则。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"one_answers"hi 3"。然而,它会产生3次"嗨3"。如果只是添加到数组中的函数的定义,而使用外部函数中定义的变量,创建了闭包,这怎么可能呢?
这是因为您需要执行上下文来定义闭包,这要到运行时才会发生。在执行数组中的函数时,i
的值为3
。在forEach
语句中,这就是执行上下文,这就是为什么输出总是使用3。
Bar
是闭包。
我们说Bar
在其环境中关闭变量msg
。
通常情况下,闭包一词的意思是:一个函数,它至少使用一个在封闭函数中的封闭范围中定义的变量。
回答您的第二个问题:(function(){ ... })()
就是它看起来的样子:一个匿名函数,而不是两个。除非它嵌套在另一个函数中,否则通常不会将其称为闭包。但是,嵌套在该匿名函数中的函数可以是闭包(而且通常是)。