-
Notifications
You must be signed in to change notification settings - Fork 16
Notes
I have tried to tune the macros so that they emit code (via :advanced compilation) that's similar to what you might write by hand in javascript, so that you can use this even for relatively performance-sensitive code.
For very performance-sensitive contexts, you can forego null-safety by using "unchecked" operations, which will throw errors if passed nil
. Two are available in js-interop: j/unchecked-get
and j/unchecked-set
, used as follows:
(j/unchecked-get o :someKey) ;; returns `o`
(j/unchecked-get o .-someKey) ;; works with renamable keys
(j/unchecked-set o :a 10 :b 20) ;; can set multiple properties at once
(j/unchecked-set o .-a 10 .-b 20)
These are not recommended unless you really need them.
The general rule is that you should use "renamable" keys (ie. use dot-syntax, like .-someKey
) for code that is run through the Closure compiler, which usually means ClojureScript code.
Objects created using js literal syntax, like #js:{:hello "world}
, do not have renamable keys, so you should use string/keyword keys to access them. Similarly, objects created from parsing JSON, for example data that you fetch from an API, are also not renamable.
(-> (fetch-post ...)
(.then (fn [post] (j/get post :title))))
It's possible to implement ILookup
for "all" JavaScript objects, as explained by Mike Fikes here. This will only have an effect on plain objects whose prototype is js/Object
, not for any other kind of object (eg. it won't work for browser events or React components). It also mutates the global js/Object
.
How it's done:
Associative destructuring is based on get, which can be mapped onto goog.object/get for JavaScript objects by extending them to ILookup:
(extend-type object ILookup (-lookup ([o k] (goog.object/get o (name k))) ([o k not-found] (goog.object/get o (name k) not-found))))