Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Working with Javascript classes

Kristian Mandrup edited this pageFeb 19, 2016 ·2 revisions

Most ClojureScript developers will at some point have to work with existing JavaScript libraries or frameworks which require an OOP approach. So you sometimes have to work with Javascript "classes" (ie.prototype hierarchies) from within your ClojureScript.

To create a classBag with setter functionsadd andprint, you might first come up with something like the following (which looks ugly as hell). There are thankfully much cleaner ways to achieve the same effect as we will demonstrate below.

(defnBag []  (this-as this           (set! (.-store this) (array))           this))  (set! (.. Bag -prototype -add)      (fn [val]        (this-as this                 (.push (.-store this) val))))  (set! (.. Bag -prototype -print)      (fn []        (this-as this                 (.log js/console (.-store this)))))  (defmybag (Bag.))(.add mybag5)(.add mybag7)(.print mybag)

You can use protocols to provide namespaced methods and a more idiomatic syntax:

(defprotocolMyBag  (add [this val])  (print [this]))(extend-type Bag  MyBag  (add [this val]  (.push (.-store this) val))  (print [this]  (.log js/console (.-store this))))(defmybag (Bag.))(add mybag2)(add mybag3)(print mybag)

You can also usedeftype and the specialObject protocol.

(deftypeBag [store]Object  (add [_ x] (.push store x))  (print [_] (.log js/console store))) (defnbag [arr] (Bag. arr))

TheObject protocol can also be used withreify for a pure functional solution.

(defnbag [store]  (reify    Object    (add [this x] (.push store x))    (print [this x] (.log js/console store))))

If you want some state to be fully encapsulated and kept private, you can refactor the constructor function as follows.

(defnbag []  (let [store (create-store)]    (reify      Object      (add [this x] (.push store x))      (print [this x] (.log js/console store)))))

This makesstore a local variable (closure), set by calling the functioncreate-store (which you must define). Happy Clojure!

Using ES7 decorators

Many of the latest front-end frameworks such as Ember, Angular and Aurelia are already leveraging ES7 decorators. To get a good overview of decorators, check outthis post

We could generate decorator functionality via one or more macros. Info on ClojureScript macros can be foundhere. Alternatively it could perhaps be done by adding decorator metadata to functions and types, and then post-process such functions.

We leave it as an exercise to the community (including you) to come up with recipes to achieve commonly used ES6/ES7 functionality such as decorators, while staying within the bounds of current ClojureScript limits (which compiles to ES3 compatible JavaScript as of 2016).

Clone this wiki locally

[8]ページ先頭

©2009-2025 Movatter.jp