문제

ClojureScript를 사용할 때 다음과 같은 변수를 통한 닫는 기능을 정의하려고 시도했습니다.

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

Rhino repr에서 다음 소스를 인쇄합니다.

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

함수는 내가 예상대로 작동하지만 x__43라는 변수에서 얻으려고 할 때 나는 그것을 얻을 수 없습니다.어디로 갔습니까?

도움이 되었습니까?

해결책

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

is currently compiled to

var x__1311 = 42;

cljs.user.foo = (function foo(n){
return (x__1311 + n);
});

The exact number attached to the x may of course vary from compilation to compilation and cljs.user would be replaced by the appropriate namespace name.

There is no attempt to conceal the generated variable from unrelated code in a JavaScript closure, so in principle it could still be modified if one went out of one's way to do so. Accidental collisions are extremely unlikely and simply will not happen with regular ClojureScript.

To discover things like the above, you can either call the compiler with {:optimizations :simple :pretty-print true} among the options or ask it to emit some JavaScript at the REPL (as provided by script/repl in the ClojureScript source tree or lein repl in a Leiningen project with ClojureScript declared as a dependency):

(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))))))

다른 팁

the x variable is defined outside the foo function, in the let binding. you can't "get it" because you're not in the scope of the let binding. that's more or less the whole point of using closures.

conceptually, let bindings are implemented as function calls:

(let [x 2] ...)

is equivalent to

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

which is probably similar to let is implemented in ClojureScript - either as a macro transformation to fn or directly to (function(x){...})(2).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top