special character | since v0.0-927 | in clojure | 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 []