special character | since v0.0-927 | ![]() | Edit |
Dots can be used inside symbols for JS interop.
(.foo bar)
=> bar.foo()
(.-foo bar)
=> bar.foo
(foo.)
=> new foo()
A dot's meaning depends on its position in the symbol:
.
(by itself), .-foo
, .foo
all refer to the interop . (special form)
.foo.
is constructor sugar, meaning (new foo)
.(ns foo.bar)
and foo.bar/baz
means that foo.bar
is a nested namespace.foo/bar.baz
or bar.baz
means bar.baz
is nested JS property access (not allowed in clojure).Dots inside symbols accidentally work as a technical shortcut in ClojureScript, but this is not valid in Clojure.
foo.bar.baz
=> foo.bar.baz
(not recommended)(foo.bar.baz)
=> foo.bar.baz()
(not recommended)Dots inside symbols are not recommended, as they are not detected by :infer-externs
. For example, no externs are generated for (foo.bar)
if ^js foo
is annotated.
For interop:
(def obj #js {:age 28, :greet #(str "Hi " %)}) (. obj greet "Bob") ;;=> "Hi Bob" (.greet obj "Bob") ;;=> "Hi Bob" (. obj -age) ;;=> 28 (.-age obj) ;;=> 28
For constructor:
(deftype Foo [x] Object (toString [_] (str "Foo:" x))) (Foo. 1) ;;=> # (new Foo 1) ;;=> #
For nested namespaces:
(ns example.nested.core) (def foo 1) example.nested.core/foo ;;=> 1
For nested JS properties. The following pairs are equivalent:
(js/console.log "HELLO") ;; "HELLO" (.log js/console "HELLO") ;; "HELLO"
cljs.core/PersistentQueue.EMPTY ;;=> #queue [] (.-EMPTY cljs.core/PersistentQueue) ;;=> #queue []