ClojureScript如何编译闭包?
问题描述:
当使用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