我正在完成一项学校作业,比较Swift和JavaScript中的高阶函数/闭包实现。
http://www.nltk.org/api/nltk.html#nltk.text.TextCollection在Swift中明确提到全局和嵌套函数作为闭包的特例,但我无法在JavaScript中找到任何类似/冲突的信息。
粗略搜索返回Apple documentation,这表明JS中的全局范围是作为闭包实现的,但我似乎无法找到可靠的证据,包括在我的报告中。 (大多数搜索只是返回JS闭包/范围的概述,这对我来说并不有用。)
如果任何JS大师都熟悉这个实现,我真的很感激这些信息。
干杯!
答案 0 :(得分:2)
字典将词汇定义为“与语言的词汇或词汇有关”。 JavaScript中函数的词法范围由代码中函数的物理位置静态定义。
var a = "Top of all";
function first(){
var b = "I am first";
function second(){
var c = "I am second";
}
}
这形成了一个词汇层次结构:
全球 - >第一 - >第二
JavaScript中的每个可能的范围都有自己的执行上下文。每个执行上下文都有自己的variableEnvironment - 这是该上下文的所有变量都存在的地方。函数的每次调用都会建立并输入一个新的执行上下文,从而建立一个新的variableEnvironment。
Take Away:每个variableEnvironment也将继承其直接词法范围的variableEnvironment 。
我也可以用这种方式构建它:每个variableEnvironment都会继承创建它的上下文的variableEnvironment 。
因此,对于上面的示例,first
继承了global的variableEnvironment,second
继承了first
的variableEnvironment。
在执行期间,每当调用新函数时,都会创建一个新的执行上下文,因此会创建一个新的variableEnvironment。这个新的variableEnvironment有一个名为outerLex
的属性,它保存了创建它的词法范围的variableEnvironment。
那么我们示例中函数second
的variableEnvironment如何看起来像?
{
c: ... // own variables
outerLex: {
b: .. // variables of outer lexical scope
outerLex: {
a: .. // global variable
}
}
}
它开始有意义了吗?这也应解释为什么变量在不同范围内以相同名称出现时会被“遮蔽”。
另请注意,变量按词汇接近度优先。
我已经解释了闭包。你在别处读到的所有理论都应该开始有意义。
最里面的variableEnvironment有一个outerLex
属性,引用它上面的variableEnvironment,从而防止外部作用域的变量被垃圾回收。垃圾收集通过检查如何以及哪些元素引用哪些元素来工作。 Read more here
即使函数first
已经返回并结束执行,函数second
仍然可以有效地引用其中定义的变量b
,因为它具有对其variableEnvironment的引用。
创建函数时,会自动继承variableEnvironment。 我们已经在上面看到,variableEnvironment的继承创建了一个函数闭包。
所以,在函数创建时会形成一个闭包,如果函数已经返回则没有任何关系(常见的神话)
此外,JavaScript对象通过引用工作。
因此,在变量环境中引用外部变量,而不是复制
每个函数都在JavaScript中创建一个闭包。 这是一个常见的误解,只有内部函数才会产生闭包,而事实并非如此。
最后,您说您需要一个文档来链接您的作业。 This should suffice ;)
[编辑]:我讨厌术语。每当outerLex
属性为空时,有些人就会说没有形成闭包。 MEH。
[编辑2]:本文中的大部分内容与网络上的内容相反。请阅读ECMA-262标准,以支持任何您的声明。