2012-01-26 12 views
11

JSから使用できるようにclojurescriptにいくつかのユーティリティlibを作成することを想像してください。例えば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  

一つの方法は次のとおりです。

(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 

質問:慣用/よりエレガントありclojurescriptで上記の方法?

答えて

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

これを行うための慣習的な方法ですか?

+0

おかげで、それは実際には慣用的に見えますが、あなたは(私たちはLIBのjsを構築している)、JSから呼び出すことはできませんJS側のいずれかから、あなたの慣用的なバージョンを使用するためには cljs.user.x.bar(3) を呼び出す必要があります: :私たちができる cljs.user.afoo.bar(3) cljs.user.afoo.cljs $ user $ IFoo $ bar(null、3) 何か不足していますか? – Lambder

+0

@ user535149これは実際には異なる質問です。何かをエクスポートしたいのであれば(defn ^:export foo [..] ...) – dnolen

+0

^:exportは「何か」が関数である限り動作します。メソッドがプロトタイプで定義されているオブジェクトをエクスポートしたいと思います。 – Lambder

14

これはのDeftypeに魔法「オブジェクト」プロトコルを追加することにより、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 
+2

タイムスタンプに注意してください。この回答は2012年1月26日(約1年後)のdnolenのものを実際に遡ったものです。これははるかにエレガントなようです。 –

関連する問題