. dot

special charactersince v0.0-927 in clojureEdit

Dots can be used inside symbols for JS interop.

  • (.foo bar) => bar.foo()
  • (.-foo bar) => bar.foo
  • (foo.) => new foo()

Details:

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.


Examples:

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 [] 

See Also: