实际关闭哪个功能?

时间:2014-06-18 08:08:10

标签: javascript scope closures

来自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'-_-

2 个答案:

答案 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)

来自Wikipedia

  

在编程语言中,闭包(也是词法闭包或函数闭包)是函数和引用环境的函数或引用

所以displayName是函数,makeFunc是引用环境的源,它们一起构成了闭包。