【问题标题】:Which function is the actual closure?哪个函数是实际的闭包?
【发布时间】:2014-06-18 08:08:09
【问题描述】:

来自 Mozilla 文档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() 中定义,并且仅在该函数的主体中可用。

所以总而言之,他们说内部函数和外部函数都变成了一个闭包..

抱歉问题已结束。我将“myFunc”误读为“makeFunc”-_-

【问题讨论】:

    标签: javascript scope closures


    【解决方案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
    

    【讨论】:

    • 当然,但问题是 Mozilla 说 makeFunc 又名外部函数是同一篇博文中的闭包。
    • @user3280015:更仔细地阅读您在问题中添加的引用:myFunc 是闭包,而不是 makeFuncmakeFunc 创建一个闭包并返回它。您只需将返回的闭包分配给名为myFuncvar。正如我在回答中解释的那样
    • 哎呀。阅读会有所帮助。抱歉,该问题已关闭;)
    【解决方案2】:

    来自Wikipedia

    在编程语言中,闭包(也称为词法闭包或函数闭包)是函数或对函数的引用以及引用环境

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

    【讨论】:

    • Mozilla 仍然一方面说 makeFunc (外部函数)是闭包,另一方面说 displayName (内部函数)是闭包.. 有点混乱
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-27
    • 1970-01-01
    • 1970-01-01
    • 2013-10-05
    • 1970-01-01
    • 2021-07-10
    • 2022-11-04
    相关资源
    最近更新 更多