Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clojurscript: extend a Javascript class

I'm trying to use a particular JavaScript framework which requires extending a base class to use it for application.

Basically I want to do the following as idiomatic ClojureScript.

class Foo extends Bar {
  constructor() { super("data") }
  method1(args) { /* do stuff */ }
}

I tried

(defn foo
  []
  (reify
    js/Bar
    (constructor [this] (super this "data"))
    (method1 [this args] )))

Which would work if I'd create a new class from Object, but as shadow-cljs correctly complains, "Symbol js/Bar is not a protocol". Also, I don't want to add methods but create a subclass that inherits somemethods and overloads others.

I thought about using proxy, but "core/proxy is not defined".

Of course I could create an instance of Bar and set! new methods, but that feels like giving up and using an inferior language.

like image 207
waechtertroll Avatar asked Dec 19 '25 06:12

waechtertroll


1 Answers

Please see answer below for more current solution!

CLJS has no built-in support for class ... extends ....

You can hack it together yourself with a bit of boilerplate, which you could generate via a macro to make it look pretty.

(ns your.app
  (:require
    [goog.object :as gobj]
    ["something" :refer (Bar)]))

(defn Foo
  {:jsdoc ["@constructor"]}
  []
  (this-as this
    (.call Bar this "data")
    ;; other constructor work
    this))

(gobj/extend
  (.-prototype Foo)
  (.-prototype Bar)
  ;; defining x.foo(arg) method
  #js {:foo (fn [arg]
              (this-as this
                ;; this is Foo instance
                ))})
like image 172
Thomas Heller Avatar answered Dec 20 '25 20:12

Thomas Heller