Use apply on native JavaScript functions
Asked Answered
H

3

5

In clojureScript the following multi-arity function

(defn sum [& xs] (reduce + xs))

can be either called via (sum 4 6 9) or by the use of (apply sum [4 6 9]) which yields the same result.

How can this be done with a native JavaScript function, such as: console.log.

(apply js/console.log [1 2 3])

This, yields the following error:

#object[TypeError TypeError: 'log' called on an object that does not implement interface Console.]
Hyalite answered 20/8, 2016 at 12:9 Comment(4)
I'm not sure about clojureScript, but in JS you need console.log.apply(console, […]) to make it work (though it's browser-specific)Minstrel
hmm... this is interesting. In planck (osx clojurescript repl) I tried this out and it worked fine. (apply js/console.log [1 2 3]) and (js/console.log 1 2 3) both print 1 and return nilAlert
this has gotta be some browser-specific thing. I just fired up a minimal figwheel project (from this template: github.com/bhauman/figwheel-template ) and sent (apply js/console.log [1 2 3]) to the browser from the figwheel repl; it logged 1 2 3 --- I'm using a current version of Chrome, what are you using?Alert
just to make sure this isn't an implementation difference on the javascript side in whatever environment you're using, what happens when you try (apply js/Math.sqrt [25])? It should return 5 without a problem.Alert
W
5

Some browsers always assuming the this is certain object, you can use .bind in js for temporal fix.

; you can use .bind on any function
(def d (.bind (.-log js/console) js/console))
(def ms ["aaa" "bbb" "barbarbar"])
(mapv d ms)

Related questions

What does this statement do? console.log.bind(console)

Why do js functions fail when I assign them to a local variable?

Wooer answered 24/8, 2016 at 5:17 Comment(0)
G
2

There might be an error in your code. apply works totally fine out of the box for JS functions:

cljs.user=> (apply js/Math.sqrt [25])
5

You can test it with this online REPL and I also tested it in my local project -- no problems so far.

cljs.user=> (apply js/console.log [1 2 3])
nil

also prints the output in the normal JS console as expected.

Gnathion answered 24/8, 2016 at 11:30 Comment(0)
D
0

Using js/a.b only works when a is global in your environment. Either way, I find this much cleaner:

(apply (.-log js/console) [1 2 3])

Note: with member functions, don't forget the first argument is this.

Decoration answered 5/2, 2019 at 17:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.