JavaScript中的递归闭包

6

enter image description here

function buildList( list ) {
  var i      = 0;
  var first  = function () {
    console.log( "in" )
    console.log( i );
  }
  var Second = function () {
    console.log( "out" )
    first();
  }
  return Second;
}

var a = buildList( [1, 2, 3] )
console.dir( a );

a(); // Here closure is created which has function first ,Here first also has one closure of itself that means recursive closure

当我在Chrome控制台中查看时,它有一个闭包,其中有一个函数first,它还有自己的闭包,即它在闭包中具有重复循环的自身函数。有人知道这里发生了什么吗?我非常困惑,为什么会出现无限闭包循环。

4
代码格式和缩进真的很难做到正确吗?无论如何,请发布一个显示你所困惑的开发工具的屏幕截图。 - user663031
我已经添加了一张截图。 - Parshuram Kalvikatte
你只需要在两个方向上有引用,而没有循环。 :) - Davin Tryon
2个回答

2
一个闭包是一种特殊的对象,结合了两个元素:函数和创建该函数时的环境。
  1. 不用困惑,代码的行为与预期相同。当您在代码中使用console.dir(a);时,它返回Second函数,我认为这对你很清楚。

  2. 现在,当您展开此函数时,它将在Closure中显示父函数(环境函数)的Second,即buildList。在代码中,它正在做相同的事情。

  3. 现在下一步是展开此function buildList,它将向您显示其子对象,这些子对象是var i = 0;function first()。您的控制台按预期显示。

  4. 现在,当您再次打开first()时,它将在Closure中显示first的父函数(环境函数),即buildList。(在步骤2中执行相同操作)。

现在,它再次重复步骤3,然后进行步骤4,并继续下去......也许你已经理解发生了什么。


@Parshuram,你正在执行你在问题中发布的相同代码吗? - Manoj Lodhi
但是我仍然没有在闭包中看到我的父函数。 - Parshuram Kalvikatte
然后它会显示正确的数据。如果您声明一个本地变量,无论是“i”还是“list”,它都会向您显示封闭在环境中的所有变量和函数,除了您返回的函数。 - Manoj Lodhi
1
@BenAston,我认为你需要在这里看一下。https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures - Manoj Lodhi
闭包是一种机制,使得自由变量对内部函数可用。这是否意味着闭包是一个对象?在我看来并不是。从概念上讲,闭包比对象更抽象。在JS实现中,闭包的关键组成部分是一个函数,对外部词法环境的引用,配置该引用的机制,导航该引用的机制以及"词法环境"的实现。因此,它超越了对象的具体化。俗语中重要的部分是对外部词法环境的引用。从任何意义上讲,闭包都不仅仅是一个特殊的对象。 - Ben Aston
显示剩余10条评论

0
开发工具显示变量a,它是指向匿名函数/闭包的变量。
在JavaScript中,函数在作用域中定义,也可以通过其函数体块定义作用域。作用域“知道”定义块内所有变量以及在函数但在其定义所在层次结构中定义的所有变量。
工具会显示返回函数(此处为“a”)的作用域。函数“first”在函数“a”的作用域中定义。
变量“first”也在您分配给变量“first”的匿名函数的作用域中已知。
这就是您在屏幕上看到的: “first”是一个包含函数的变量。在该函数的作用域中,“first”变量指向一个函数。在该函数的作用域中…
明白了吗?

如果你说第一个也有它自己的作用域,那么为什么第二个没有自己的作用域呢?它只有第一个和列表作用域吗? - Parshuram Kalvikatte
是的,看起来 Chrome 调试器只显示在该作用域中使用的变量。请参见您屏幕截图输出的第三行代码文本。 - Peter Paul Kiefer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接