2011-02-28 47 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

相關問題