ClojureScript如何编译闭包?

时间:2012-03-01 16:08:24

标签: clojure closures clojurescript

当使用ClojureScript时,我试图定义一个函数,它是对这个变量的闭包:

(let [x 42] 
  (defn foo [n] (+ x n)))

在Rhino REPL打印以下来源:

function foo(n){
  return cljs.core._PLUS_.call(null,x__43,n);
}

该函数按预期工作,但在尝试获取名为x__43的变量时,我无法得到它。它去了哪里?

2 个答案:

答案 0 :(得分:5)

x变量在foo函数之外定义,在let绑定中。你不能“得到它”,因为你不在let绑定的范围内。这或多或少都是使用闭包的重点。

从概念上讲,让绑定实现为函数调用:

(let [x 2] ...)

相当于

((fn [x] ...) 2)

可能类似于let在ClojureScript中实现 - 作为对fn的宏转换或直接转换为(function(x){...})(2)

答案 1 :(得分:4)

(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}调用编译器,或者要求它在REPL中发出一些JavaScript(由ClojureScript源代码树中的script/repl提供或{1}在Leiningen项目中,ClojureScript被声明为依赖项):

lein repl