2011-02-28 49 views
7

我对编译器理论以及传统过程和面向对象语言(如C,Pascal和Java)的运行时环境非常熟悉。我期待详细了解像JavaScript这样的语言的运行时结构如何实现,特别是与闭包相关的问题:存储是如何管理的,何时分配闭包,如何决定何时释放闭包存储。通过挖掘V8或Rhino的源代码,您能否指出我可以提供这种描述的论文或书籍或教程?我在哪里可以找到关于实现闭包的详细信息(如在JavaScript或Scheme中)?

谢谢。

+0

[这篇文章](http://mrale.ph/blog/2012/09/23/grokking-v8-closures-for-fun.html)是一个经典。 – 2015-05-01 19:18:28

回答

1

它相当简单,它是嵌套命名空间的克隆,与编译器理论相反,它是运行时分配的命名空间,用于解析符号查找,与将符号编译为静态偏移量的编译语言相比。

但基本上所有的含义是,符号查找是从名称空间的链接列表(从本地名称空间开始到封闭名称空间(封闭))发生的。

和在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来源为:

http://code.google.com/p/chibi-scheme/

+0

不是一种编译语言吗?而且,由于JavaScript在某种程度上具有词汇范围,因此在那里执行运行时查找也不是完全必要的。 – 2011-03-01 11:33:06

1

这种技术被称为lambda lifting,这完全是静态的(所以,不需要昂贵的运行时名称空间查找)。

1

This article解释了在JavaScript中实现闭包。

+0

伟大的链接,不知道为什么它downvoted? – 0fnt 2014-11-23 15:24:57

+0

@ user247077:谢谢!直接回答优于回答链接,因此SO页面将自成一体。然后也存在链接断开的问题。这就是SO理念! – rahulmohan 2014-12-12 14:52:59

相关问题