我对编译器理论以及传统过程和面向对象语言(如C,Pascal和Java)的运行时环境非常熟悉。我期待详细了解像JavaScript这样的语言的运行时结构如何实现,特别是与闭包相关的问题:存储是如何管理的,何时分配闭包,如何决定何时释放闭包存储。通过挖掘V8或Rhino的源代码,您能否指出我可以提供这种描述的论文或书籍或教程?我在哪里可以找到关于实现闭包的详细信息(如在JavaScript或Scheme中)?
谢谢。
我对编译器理论以及传统过程和面向对象语言(如C,Pascal和Java)的运行时环境非常熟悉。我期待详细了解像JavaScript这样的语言的运行时结构如何实现,特别是与闭包相关的问题:存储是如何管理的,何时分配闭包,如何决定何时释放闭包存储。通过挖掘V8或Rhino的源代码,您能否指出我可以提供这种描述的论文或书籍或教程?我在哪里可以找到关于实现闭包的详细信息(如在JavaScript或Scheme中)?
谢谢。
它相当简单,它是嵌套命名空间的克隆,与编译器理论相反,它是运行时分配的命名空间,用于解析符号查找,与将符号编译为静态偏移量的编译语言相比。
但基本上所有的含义是,符号查找是从名称空间的链接列表(从本地名称空间开始到封闭名称空间(封闭))发生的。
和在JavaScript的命名空间仅仅是与任何开放函数的参考计数的对象与该命名空间
例如参考
var links = //a list of links identified set somehwere else
for(var i = 0, l = 3; l--; i++){
(function(n){
links[i].onclick = function(){ alert(n); }
})(i)
}
在上面的代码
,链接[i]是用于访问阵列,但在链接被点击时,我将已经递增,从而不相同的数量的链接。所以n被设置在父命名空间中,所以当它触发alert(n)时将是准确的。
global
|
|\
| +-- function(n=0) <- link0.onclick = function()
|\
| +-- function(n=1) <- link1.onclick = function()
\
+-- function(n=2) <- link2.onclick = function()
这分成3个堆栈帧,每个迭代一个i。并且hte'onclick ='表达式右侧的函数有一个对栈帧的引用,因为它是词法父元素,它开始它的符号查找。
他们最终都会看到相同的命名空间,因为他们共享一个祖父母。
一些链接:
https://developer.mozilla.org/en/a_re-introduction_to_javascript
这个最小的方案更容易比V8来源为:
不是一种编译语言吗?而且,由于JavaScript在某种程度上具有词汇范围,因此在那里执行运行时查找也不是完全必要的。 – 2011-03-01 11:33:06
这种技术被称为lambda lifting,这完全是静态的(所以,不需要昂贵的运行时名称空间查找)。
This article解释了在JavaScript中实现闭包。
伟大的链接,不知道为什么它downvoted? – 0fnt 2014-11-23 15:24:57
@ user247077:谢谢!直接回答优于回答链接,因此SO页面将自成一体。然后也存在链接断开的问题。这就是SO理念! – rahulmohan 2014-12-12 14:52:59
[这篇文章](http://mrale.ph/blog/2012/09/23/grokking-v8-closures-for-fun.html)是一个经典。 – 2015-05-01 19:18:28