Clojurescript:扩展 Javascript class
Clojurscript: extend a Javascript class
我正在尝试使用特定的 JavaScript 框架,该框架需要扩展基础 class 才能将其用于应用程序。
基本上我想按照惯用的 ClojureScript 执行以下操作。
class Foo extends Bar {
constructor() { super("data") }
method1(args) { /* do stuff */ }
}
我试过了
(defn foo
[]
(reify
js/Bar
(constructor [this] (super this "data"))
(method1 [this args] )))
如果我从 Object 创建一个新的 class,这会起作用,但是正如 shadow-cljs
正确地抱怨的那样,"Symbol js/Bar is not a protocol"。另外,我不想添加方法,而是创建一个继承某些方法并重载其他方法的子class。
我考虑过使用 proxy
,但 "core/proxy is not defined"。
当然我可以创建 Bar
的实例和 set!
新方法,但这感觉就像放弃并使用劣质语言。
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
))})
CLJS(仍然)没有 built-in 支持 class ... extends ...
。
但是在最近的 shadow-cljs
版本中,我添加了对 class
和 extends
的支持。这将发出一个标准的 JS class
并且不需要任何 hacky 变通办法来让它工作。
翻译这个例子
class Foo extends Bar {
constructor() { super("data") }
method1(args) { /* do stuff */ }
}
会是
(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
))
可以找到 defclass
的更复杂示例 here and here。
目前这仅与 shadow-cljs 一起提供,但从技术上讲,您可以从 here 获取 modern.cljc
和 modern.cljs
文件并将它们放入您的项目中。它应该适用于所有构建工具。
我正在尝试使用特定的 JavaScript 框架,该框架需要扩展基础 class 才能将其用于应用程序。
基本上我想按照惯用的 ClojureScript 执行以下操作。
class Foo extends Bar {
constructor() { super("data") }
method1(args) { /* do stuff */ }
}
我试过了
(defn foo
[]
(reify
js/Bar
(constructor [this] (super this "data"))
(method1 [this args] )))
如果我从 Object 创建一个新的 class,这会起作用,但是正如 shadow-cljs
正确地抱怨的那样,"Symbol js/Bar is not a protocol"。另外,我不想添加方法,而是创建一个继承某些方法并重载其他方法的子class。
我考虑过使用 proxy
,但 "core/proxy is not defined"。
当然我可以创建 Bar
的实例和 set!
新方法,但这感觉就像放弃并使用劣质语言。
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
))})
CLJS(仍然)没有 built-in 支持 class ... extends ...
。
但是在最近的 shadow-cljs
版本中,我添加了对 class
和 extends
的支持。这将发出一个标准的 JS class
并且不需要任何 hacky 变通办法来让它工作。
翻译这个例子
class Foo extends Bar {
constructor() { super("data") }
method1(args) { /* do stuff */ }
}
会是
(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
))
可以找到 defclass
的更复杂示例 here and here。
目前这仅与 shadow-cljs 一起提供,但从技术上讲,您可以从 here 获取 modern.cljc
和 modern.cljs
文件并将它们放入您的项目中。它应该适用于所有构建工具。