来自Mozilla Doc https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures:
function makeFunc() {
var name = "Mozilla";
function displayName() {
alert(name);
}
return displayName;
}
var myFunc = makeFunc();
myFunc();
不是displayName是实际的闭包,因为它关闭了外部函数makeFunc的作用域以供以后使用吗? Mozilla说makeFunc是关闭的:
这个难题的解决方案是myFunc已成为一个闭包。闭包是一种特殊的对象,它结合了两个东西:一个函数,以及创建该函数的环境。
我记得读过不同的定义..
Mozilla也对他们所说的以下代码自相矛盾:
function init() {
var name = "Mozilla"; // name is a local variable created by init
function displayName() { // displayName() is the inner function, a closure
alert (name); // displayName() uses variable declared in the parent function
}
displayName();
}
init();
init()创建一个局部变量名,然后一个名为displayName()的函数displayName()是内部函数(一个闭包) - 它在init()中定义,并且只在该函数体内可用。 / p>
总而言之,他们说内部函数和外部函数都已成为闭包..
抱歉的问题。我把'myFunc'误读为'makeFunc'-_-
答案 0 :(得分:1)
我认为你误解了文档 - myFunc
是封闭,但是makeFunc
,就像你想象的那样。:
init()
创建一个局部变量名,然后创建一个名为displayName()
的函数。displayName()
是内部函数(闭包) - 它在init()
内定义,并且只在该函数的主体内可用。与init()
不同,displayName()
没有自己的局部变量,而是重用父函数中声明的变量名。
只需将init
替换为makeFunc
,然后将上面的引用应用到您的代码中。 displayName
是返回的内容,因此被暴露。它是一个可以访问var name
的函数对象
所以是的,displayName
是一个闭包,它是由makeFunc
返回的和创建的闭包。
当您将此返回的闭包分配给变量时,该变量就是该闭包。在您的情况下,myFunc
被赋予了createFunc
的返回值,意味着它被分配了一个函数实例,在其自身内部称为displayName
,可以访问var name
。
下次调用createFunc
时,将创建 new name
var,并创建一个新的displayName
函数。如果你将它分配给另一个var,那么你有2个闭包,即使它们在内部使用相同的变量名,并且它们都是由同一个函数返回的,也是2个独立的闭包。
在JS中,函数是第一类对象(意味着它们可以像任何其他值一样传递和分配)。这意味着:
var foo = function (bar) //assign function to variable foo
{
return function()//this function will return a function
{
bar();//that invokes bar, an argument passed to the outer function
alert('bar was invoked');
};
}
var closure = foo(function(){ alert('test');});//pass function to foo
//returns the inner function, that invokes the function we just passed:
closure();//will alert "test", and then "bar was invoked"
var closure2 = foo(function(){ alert('a new closure');});
closure2();//alerts "a new closure" and "bar was invoked"
closure();// still alerts the same
答案 1 :(得分:0)