ClojureScript中console.log的几种写法哪种更符合惯用规范?
console.log Syntax is Idiomatic? Great question! Let's walk through the options you've listed and clarify which is the most idiomatic, plus address that interesting shadow-cljs quirk you found.
Comparing the Valid Syntax Options
First, let's recap the three ways you've noted to produce console.log("Hello") in ClojureScript:
(.log js/console "Hello")(js/console.log "Hello")(console.log "Hello")
The Most Idiomatic Choice: (js/console.log "Hello")
This is the standard, idiomatic way to call JavaScript's console.log in ClojureScript, and here's why:
- The
js/prefix explicitly signals that we're accessing a JavaScript global object, which makes the code's intent crystal clear—anyone reading it immediately knows this is interop with JS, not a native ClojureScript function. - It mirrors JavaScript's own syntax closely (
console.log("Hello")), making it intuitive for both CLJS and JS developers to read.
Why the Other Options Are Less Ideal
(.log js/console "Hello"): This uses Clojure's Java-style instance method invocation syntax, which is valid in CLJS but has fallen out of favor for JS interop. Thejs/console.logform is more concise and aligns better with modern CLJS conventions.(console.log "Hello"): While this works in some environments, it relies on implicit mapping of unqualified symbols to JS globals. This is risky because:- If you ever define a ClojureScript function named
console.log(unlikely but possible), you'll hit a naming conflict. - It's not portable across all CLJS build tools—this implicit mapping isn't part of standard ClojureScript, so it might fail in tools other than shadow-cljs.
- If you ever define a ClojureScript function named
That Shadow-Cljs Quirk: (console.log) Working Without Arguments
Your observation that (console.log) works in shadow-cljs is specific to that build tool. Shadow-cljs includes convenience features that auto-expose JS globals without requiring the js/ prefix, which is why this bare form works. However, this is not standard ClojureScript behavior—if you moved this code to another tool like Figwheel or Leiningen, it would throw an error because console wouldn't be recognized as a valid symbol in the CLJS namespace.
For consistency and portability, even in shadow-cljs, it's better to stick with (js/console.log) when you need to call it without arguments.
内容的提问来源于stack exchange,提问作者Quang Van

