Clojurscript:扩展一个 Javascript 类

wae*_*oll 1 clojurescript clojurescript-javascript-interop

我正在尝试使用特定的 JavaScript 框架,该框架需要扩展基类以将其用于应用程序。

基本上我想按照惯用的 ClojureScript 执行以下操作。

class Foo extends Bar {
  constructor() { super("data") }
  method1(args) { /* do stuff */ }
}
Run Code Online (Sandbox Code Playgroud)

我试过

(defn foo
  []
  (reify
    js/Bar
    (constructor [this] (super this "data"))
    (method1 [this args] )))
Run Code Online (Sandbox Code Playgroud)

如果我从 Object 创建一个新类,这会起作用,但正如shadow-cljs正确抱怨的那样,“Symbol js/Bar 不是协议”。另外,我不想添加方法,而是创建一个继承某些方法并重载其他方法的子类。

我想过使用proxy,但“未定义核心/代理”。

当然,我可以创建的实例Barset!新方法,但感觉就像放弃和使用质量较低的语言。

Tho*_*ler 12

CLJS(仍然)没有对class ... extends ....

然而,在最近的shadow-cljs版本中,我添加了对class以及 的支持extends。这将发出一个标准的 JS class,并且不需要任何 hacky 解决方法即可使其工作。

翻译一下这个例子

class Foo extends Bar {
  constructor() { super("data") }
  method1(args) { /* do stuff */ }
}
Run Code Online (Sandbox Code Playgroud)

将会

(ns your.app
  (:require [shadow.cljs.modern :refer (defclass)]))

(defclass Foo
  ;; extends takes a symbol argument, referencing the super class
  ;; could be a local symbol such as Bar
  ;; a namespaced symbol such as alias/Bar
  ;; or just a global via js/Bar
  (extends Bar)

  (constructor [this]
    (super "data"))

  ;; adds regular method, protocols similar to deftype/defrecord also supported
  Object
  (method1 [this args]
    ;; do stuff
    ))
Run Code Online (Sandbox Code Playgroud)

更复杂的例子可以在这里这里defclass找到。

目前,这只随 Shadow-cljs 一起提供,但从技术上讲,您可以从这里获取modern.cljc和文件并将它们放入您的项目中。那么它应该可以与所有构建工具一起使用。modern.cljs


Tho*_*ler 6

CLJS 没有对class ... extends ....

你可以自己用一些样板来破解它,你可以通过宏生成它以使其看起来很漂亮。

(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
                ))})
Run Code Online (Sandbox Code Playgroud)