在clojurescript中扩展deftype的构造函数

时间:2013-05-18 07:08:11

标签: javascript clojure clojurescript

在clojurescript中通过deftype创建类型时:

(deftype SomeObject [a b c]
    Object
        (update [_]
            (set! (.-a _) 5)
            (set! (.-b _) 6) ))

是否有可能扩展构造函数?我想在创建对象时对其进行一些初始化!

3 个答案:

答案 0 :(得分:3)

deftype中没有支持,没有; Clojure(Script)等效于定义工厂函数,可能是make-some-object,并使用它而不是实际的构造函数。有关示例和基本原理,请参阅amalloy的答案。

当然在JavaScript中,构造函数只是函数,您当然可以使用ClojureScript定义一个函数,该函数将作为JS构造函数使用:

;; "constructor" with default field values
(defn Point [x y]
  (this-as this
    (set! (.-x this) (if x x 10)) ; NB. Clojure truth semantics are used
    (set! (.-y this) (if y y 20))))

(.-x (Point. 2))
;= 2
(.-y (Point. 2))
;= 20

这有点违背语言的整体精神,除非在特殊情况下,否则不可取。 (与期望构造函数作为参数的JS API互操作?)

答案 1 :(得分:2)

deftype的构造函数是故意简约的:它只复制N个对象来保存数据字段。没有必要让它更强大,因为你已经有了一个工具来完成这项工作:只需要简单的旧功能。

(defn foo [opts]
  (if-not (acceptable? opts) 
    (throw (Exception. "No way, man"))
    (Foo. (:x opts) (:y opts)))

是包装deftype构造函数的简单示例。即使deftype允许你用这种逻辑灌输“真正的”构造函数,在客户端API和底层表示之间创建一个抽象屏障也是很好的,这样如果表示发生变化,客户端代码可能主要不受影响。

答案 2 :(得分:0)

谢谢大家,我会选择工厂方法。无论如何,可能在ClojureScript中最有意义!我想我将来会尝试避免使用deftypes / Types,因此工厂方法可以很好地隐藏它。仍处于功能编程的过渡阶段;)