小编Lam*_*der的帖子

如何在ClojureScript中使用方法和构造函数创建JS对象

想象一下,任务是在clojurescript中创建一些实用程序库,以便可以从JS中使用它.

例如,假设我想生成相当于:

    var Foo = function(a, b, c){
      this.a = a;
      this.b = b;
      this.c = c;    
    }

    Foo.prototype.bar = function(x){
      return this.a + this.b + this.c + x;
    }

    var x = new Foo(1,2,3);

    x.bar(3);           //  >>  9    
Run Code Online (Sandbox Code Playgroud)

实现这一目标的一种方法是:

    (deftype Foo [a b c])   

    (set! (.bar (.prototype Foo)) 
      (fn [x] 
        (this-as this
          (+ (.a this) (.b this) (.c this) x))))

    (def x (Foo. 1 2 3))

    (.bar x 3)     ; >> 9
Run Code Online (Sandbox Code Playgroud)

问题:clojurescript中有更优雅/惯用的方法吗?

javascript interop clojure clojurescript

11
推荐指数
2
解决办法
2736
查看次数

6
推荐指数
1
解决办法
7719
查看次数

具有类型提示的动态功能

我正在尝试使用提示参数在运行时生成函数.

参数符号在运行时期间是已知的.

如果我事先知道它们,我可以像这样动态创建函数:

(def foo 
  (eval 
    (list 'fn '[^String a] (list '.length 'a))))
Run Code Online (Sandbox Code Playgroud)

具有理想的性能:

user=> (time (reduce + (map foo (repeat 1000000 "asdf")  )))
"Elapsed time: 164.578 msecs"
4000000
Run Code Online (Sandbox Code Playgroud)

而不是:

(def bar
  (eval 
    (list 'fn '[a] (list '.length 'a))))

user=> (time (reduce + (map bar (repeat 1000000 "asdf")  )))
"Elapsed time: 2392.271 msecs"
4000000
Run Code Online (Sandbox Code Playgroud)

现在.我遇到的问题是如何使用动态参数列表在运行时创建这样的函数.例如:

(def baz
  (let [args '[a b]]    
    (eval
      (list 
        'fn 
        (vec (flatten (map (fn [ar] `[^String ~ar]) args))) 
        (list '.length (first args))))))
#'user/baz

user=> (time (reduce …
Run Code Online (Sandbox Code Playgroud)

metadata eval clojure dynamic

2
推荐指数
1
解决办法
314
查看次数

习惯上等同于以下Clojure代码

Clojure中是否有任何特殊的形式或功能,相当于:

(defn foo [ob col f] 
  (reduce 
     #(f %1 %2) 
     ob col))
Run Code Online (Sandbox Code Playgroud)

基本上类似于doto但是在Clojure数据结构上工作而不是在可变java对象上.

clojure

1
推荐指数
1
解决办法
74
查看次数