Transparent interoperability
Clojure lets you write code close to the metal ie the host language. In this chapter, we'll learn about constructs and techniques to interact with JavaScript within Clojure.
Clojure doesn't hide the underlying host from the developer. It lets you bypass Clojure and write code close to the metal. This chapter on interop is focused on JavaScript as a host, but most of the concepts will apply to other hosts too. The code examples in this chapter are in the first-project.interop
namespace.
js
namespace#
JavaScript objects like Array
, Date
, Math
, and Object
are accessible via the js/
namespace. You can evaluate these forms and check what they look like:
js/Math ;; => #js {}
js/Array ;; => #object[Array]
(type js/Array) ;; => #object[Function]
In a browser environment, you can access the window
object using js/window
.
Instantiating objects#
To create instances of JS objects, we can use the new
function or the .
dot suffix:
(new js/Date) ;; => #inst "2020-08-14T06:39:35.529-00:00"
(js/Date.) ;; => #inst "2020-08-14T06:39:49.126-00:00"
All arguments passed are passed down to the constructor:
(new js/Array 1 2 3) ;; => #js [1 2 3]
(js/Array. 1 2 3) ;; => #js [1 2 3]
Notice the #js
prefix in the result of the inline evaluation. This signifies that the data structure is not a CLJS vector but a JS Array.
The forms (new js/Foo p q r)
and (js/Foo. p q r)
are equal to new Foo(p, q, r);
. You can use Klipse to check the transpilation in real-time.
Calling object methods#
A method bar
on object Foo
can be called using (.bar Foo p q r)
. This is equal toFoo.bar(p, q, r)
in the JS domain:
;; same as Date.now()
(.now js/Date) ;; => 1597388702083
;; same as (new Array(1, 2, 3)).map(i => i + 1)
(.map (new js/Array 1 2 3) inc)
The now
method on the js/Date
object is a static function, ie doesn't require an initialized object. The .map
method on js/Array
is an instance method, ie requires an instance of Array
to operate on.
A static method bar
defined for a class Foo
can be alternatively called using (js/Foo.bar)
. We can rewrite the now
function call as:
(js/Date.now) ;; => 1597389177815
This page is a preview of Tinycanva: Clojure for React Developers