Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ClojureScript property accessor function

I have a need to pass a property accessor to a function, for example:

(defn test [access]
  (.log js/console (str (access js/window))))

(test #(.-screenLeft %))

Is this the best way to do it? The following doesn't work:

(test .-screenLeft)
like image 460
jbouwman Avatar asked Jul 24 '26 14:07

jbouwman


2 Answers

Generally speaking, yours is the canonical way to do it in Clojure.

In ClojureScript that's also typically the best approach; the major gotcha is that there are two ways to introduce properties in JavaScript and ClojureScript:

  • index style -- a["foo"] / (aget a "foo");

  • dotted property style -- a.foo / (.-foo a).

You need to make sure that you're not mixing them for the same property if you want your code to compile in advanced mode. (Mixing in the sense of introducing the property with one pattern, then accessing with the other.) This is because the Google Closure compiler feels free to rename properties introduced with the dotted property style, while those introduced with the index style it leaves alone.

NB. this doesn't apply to explicitly exported properties and symbols provided by the JavaScript environment (js/alert etc.).

like image 78
Michał Marczyk Avatar answered Jul 28 '26 15:07

Michał Marczyk


I think that your solution is fine, but you might like something like this a little better:

(defn test [access]
  (->> access name (aget js/window) str (.log js/console)))

By taking advantage of name, you can now access the property screenLeft any of these ways:

(test :screenLeft) 
(test 'screenLeft)
(test "screenLeft")
like image 31
DaoWen Avatar answered Jul 28 '26 17:07

DaoWen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!