LoginSignup
9
8

More than 5 years have passed since last update.

#jsとclj->jsの違いについて

Posted at

ClojureScriptのオブジェクトからJavaScriptのオブジェクトに変換する方法として#jsclj->jsがありますが、その違いは何でしょうか?

(identity #js [[[1 2]]])
(clj->js [[[1 2]]])

#jsはvectorとmapのみ変換可能で、再帰的には適用されません。
clj->jsはlistやsetも変換可能で、再帰的に適用されます。

コードを見るとそれがよくわかります。
#jsは以下のread-jsが本体です。

reader.cljs抜粋
(defn ^:private read-js
  [form]
  (cond
    (vector? form)
    (let [arr (array)]
      (doseq [x form]
        (.push arr x))
      arr)

    (map? form)
    (let [obj (js-obj)]
      (doseq [[k v] form]
        (aset obj (name k) v))
      obj)

    :else
    (reader-error nil
      (str "JS literal expects a vector or map containing "
           "only string or unqualified keyword keys"))))

clj->jsは以下です。keywordやsymbolも変換されるようです。

core.cljs抜粋
(defn clj->js
   "Recursively transforms ClojureScript values to JavaScript.
sets/vectors/lists become Arrays, Keywords and Symbol become Strings,
Maps become Objects. Arbitrary keys are encoded to by key->js."
   [x]
   (when-not (nil? x)
     (if (satisfies? IEncodeJS x)
       (-clj->js x)
       (cond
         (keyword? x) (name x)
         (symbol? x) (str x)
         (map? x) (let [m (js-obj)]
                    (doseq [[k v] x]
                      (aset m (key->js k) (clj->js v)))
                    m)
         (coll? x) (let [arr (array)]
                     (doseq [x (map clj->js x)]
                       (.push arr x))
                     arr)
         :else x))))
9
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
8