當使用ClojureScript我試圖定義一個函數,它是在這樣的可變的封閉:ClojureScript如何編譯閉包?
(let [x 42]
(defn foo [n] (+ x n)))
,打印在犀牛REPL以下源:
function foo(n){
return cljs.core._PLUS_.call(null,x__43,n);
}
功能工程,我期望但是當試圖得到名爲x__43
的變量時,我無法得到它。它去了哪裏?
當使用ClojureScript我試圖定義一個函數,它是在這樣的可變的封閉:ClojureScript如何編譯閉包?
(let [x 42]
(defn foo [n] (+ x n)))
,打印在犀牛REPL以下源:
function foo(n){
return cljs.core._PLUS_.call(null,x__43,n);
}
功能工程,我期望但是當試圖得到名爲x__43
的變量時,我無法得到它。它去了哪裏?
(let [x 42]
(defn foo [n] (+ x n)))
目前編譯爲
var x__1311 = 42;
cljs.user.foo = (function foo(n){
return (x__1311 + n);
});
附接到x
當然可以從彙編變化到彙編和cljs.user
將由適當的名稱空間名替換的確切數目。
沒有試圖在JavaScript關閉中隱藏不相關代碼中的生成變量,所以原則上如果有人不這樣做,它仍然可以被修改。偶然的碰撞是極不可能的,而且在普通的ClojureScript中不會發生。
要發現之類的東西上面,你可以調用編譯器選項中{:optimizations :simple :pretty-print true}
或要求它發出一些JavaScript在REPL(如通過在ClojureScript源代碼樹script/repl
或lein repl
與ClojureScript一個Leiningen項目提供宣佈爲依賴):
(require '[cljs.compiler :as comp])
(binding [comp/*cljs-ns* 'cljs.user]
(comp/emit
(comp/analyze {:ns {:name 'cljs.user} :context :statement :locals {}}
'(let [x 42] (defn foo [n] (+ x n))))))
x變量是在foo函數外定義的,在let綁定中。你不能「得到它」,因爲你不在let綁定的範圍內。這或多或少是使用閉包的關鍵。
概念,讓綁定實現函數調用:
(let [x 2] ...)
相當於
((fn [x] ...) 2)
這是可能類似let
在ClojureScript實現 - 無論是作爲宏觀轉型fn
或直接到(function(x){...})(2)
。
你是什麼意思,你「不能得到它」?你的意思是評估Rhine repl上的'x__43'是不確定的嗎? – liwp 2012-03-01 16:21:42