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

Lam*_*der 11 javascript interop clojure clojurescript

想象一下,任务是在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中有更优雅/惯用的方法吗?

kan*_*aka 17

通过在defotype中添加一个神奇的"对象"协议,使用JIRA CLJS-83解决了这个问题:

(deftype Foo [a b c]
  Object
  (bar [this x] (+ a b c x)))
(def afoo (Foo. 1 2 3))
(.bar afoo 3) ; >> 9
Run Code Online (Sandbox Code Playgroud)

  • 记下时间戳.这个答案实际上是在2012年1月26日(大约一年后)的dnolen之后,这看起来更优雅. (2认同)

dno*_*len 12

(defprotocol IFoo
  (bar [this x]))

(deftype Foo [a b c]
  IFoo
  (bar [_ x]
    (+ a b c x)))

(def afoo (Foo. 1 2 3))
(bar afoo 3) ; >> 9
Run Code Online (Sandbox Code Playgroud)

这是惯用的方式吗?