JavaScript中的全局/嵌套函数是作为闭包实现的吗?

我正在研究一个学校作业,比较
Swift
JavaScript中的高阶函数/闭包实现.

Apple documentation明确提到了Swift中的全局和嵌套函数作为闭包的特例,但我无法在JavaScript中找到任何类似/冲突的信息.

粗略搜索返回this blog post,这表明JS中的全局范围是作为一个闭包实现的,但我似乎找不到可靠的证据,包括在我的报告中. (大多数搜索只返回JS闭包/范围的概述,这对我没用.)

如果任何JS专家都熟悉这个实现,我真的很感激这些信息.

干杯!

最佳答案 词汇范围

词典将词汇定义为“与语言的词汇或词汇有关”. JavaScript中函数的词法范围由代码中函数的物理位置静态定义.

var a = "Top of all";

function first(){
 var b = "I am first";
  function second(){
   var c = "I am second";
   }
}

这形成了一个词法层次结构:

全球 – >第一 – >第二

variableEnvironment Read 10.4 and 10.5

JavaScript中的每个可能的范围都有自己的执行上下文.每个执行上下文都有自己的variableEnvironment – 这是该上下文的所有变量都存在的地方.每次调用函数都会建立并输入新的执行上下文,从而建立一个新的variableEnvironment.

Take Away:每个variableEnvironment也将继承其直接词法范围的variableEnvironment.

我也可以用这种方式构建它:每个variableEnvironment都继承创建它的上下文的variableEnvironment.

因此对于上面的例子,首先继承global的variableEnvironment,然后继承first的variableEnvironment.

这种遗产如何运作?

在执行期间,每当调用新函数时,都会创建一个新的执行上下文,因此会创建一个新的variableEnvironment.这个新的variableEnvironment有一个名为outerLex的属性,它保存创建它的词法范围的variableEnvironment.

那么我们的例子中函数second的变量环境如何?

{
 c: ... // own variables
 outerLex: {
   b: .. // variables of outer lexical scope
   outerLex: {
      a: .. // global variable
   }

 }
}

它开始有意义了吗?这也应解释为什么变量在不同范围内以相同名称出现时会被“遮蔽”.

还要注意,变量按词法接近度排列优先级.

我已经解释了闭包.你在别处读到的所有理论都应该开始有意义.

最里面的variableEnvironment有一个outerLex属性,它引用它上面的variableEnvironment,从而防止外部作用域的变量被垃圾收集.垃圾收集通过检查如何以及哪些元素引用哪些元素来工作. Read more here

即使函数首先返回并结束执行,函数second仍然可以有效地引用其中定义的变量b,因为它具有对其variableEnvironment的引用.

让我们深入挖掘(并回答你的问题)

创建函数时,将自动继承variableEnvironment.
我们已经在上面看到,variableEnvironment的继承创建了一个函数闭包.

因此,在函数创建时形成一个闭包,如果函数已经返回,它就无所事事(常见的神话)

此外,JavaScript对象通过引用工作.

因此,外部变量被引用,而不是复制到variableEnvironment中

回答你的问题

每个函数都在JavaScript中创建一个闭包.
一个常见的误解是只有内部函数才会产生闭包,而事实并非如此.

全局范围中的函数也形成闭包,但它们的闭包很无聊,因为它只引用全局变量环境,它在任何情况下都是可见的.

最后,您说您需要一个文档来链接您的作业. This should suffice 😉

[编辑]:我讨厌术语.每当outerLex属性为空时,有些人都喜欢说没有形成闭包.咩.

[编辑2]:本文中的大部分内容与网络上的内容相反.请阅读ECMA-262标准以支持您的任何索赔.

点赞