2024年Clojure状态调查!中分享您的想法。

欢迎!请查看关于页面以获取更多关于如何使用本站的信息。

+3
ClojureScript

版本:1.9.946
从问题CLJS-1998跟进

`
cljs.user=> (js->clj #js {})
{}

cljs.user=> (js->clj (.create js/Object nil))

object[Object]

cljs.user=> (keys (js->clj (.create js/Object nil)))
org.mozilla.javascript.EcmaError: TypeError: Cannot find default value for object. (.cljs_rhino_repl/goog/../.cljs_rhino_repl/cljs/core.js#9915)

 (.cljs_rhino_repl/cljs/core.cljs:2930:10)
 cljs$core$seq (.cljs_rhino_repl/cljs/core.cljs:1212:13)
 cljs$core$keys (.cljs_rhino_repl/cljs/core.cljs:8648:3)
 (NO_SOURCE_FILE <cljs repl>:1:0)
 (NO_SOURCE_FILE <cljs repl>:1:0)

`

5个回答

0

评论者:kurtharriger

为此,null原型对象的来源是由我使用的第三方库生成的,以下为源代码:https://github.com/ProseMirror/prosemirror-model/blob/cdded3d/src/schema.js#L13

0

评论者:kurtharriger

(def a (.create js/Object null)) => #'cljs.user/a (type a) => nil

js->clj的实现显式检查了js/Object类型。

`
(defn js->clj
"递归地将JavaScript数组转换为ClojureScript向量,将JavaScript对象转换为ClojureScript映射。如果设置':keywordize-keys true',则将对象字段从字符串转换为关键字。")




(let (link: {:keys [keywordize-keys)} opts
      keyfn (if keywordize-keys keyword str)
      f (fn thisfn (link: x)
          (cond
            (satisfies? IEncodeClojure x)
            (-js->clj x (apply array-map opts))

            (seq? x)
            (doall (map thisfn x))

            (coll? x)
            (into (empty x) (map thisfn x))

            (array? x)
            (vec (map thisfn x))

            (identical? (type x) js/Object)
            (into {} (for (link: k (js-keys x))
                       (link: (keyfn k) (thisfn (unchecked-get x k)))))

            :else x))

`

我认为也许这个最后的测试应该改为 (or (nil? (type a)) (identical? (type x) js/Object)),因为创建具有空原型的对象的唯一方法是显式的,他们这样做是因为它们打算用作关联对象。(http://adripofjavascript.com/blog/drips/creating-objects-without-prototypes.html)

0

评论者:kurtharriger

以上也表明,也许可以在nil上扩展IEncodeClojure?
a不是nil,但它的类型是...那么,也许在nil上扩展协议可以这样工作?

但不起作用...也许这是satisfies?的一个bug?

`
cljs.user=> (def a (.create js/Object nil))

'cljs.user/a

cljs.user=> (aset a "test" 1)
1
cljs.user=> (extend-protocol IEncodeClojure)
nil
(-js->clj (link: x opts)

(let (link: {:keys [keywordize-keys)} opts
      keyfn (if keywordize-keys keyword str)]
  (into {} (for (link: k (js-keys x))
    (link: (keyfn k) (js->clj (unchecked-get x k)) opts))))))

nil
cljs.user=> (js->clj a)

object(link: Object)

cljs.user=> (js-keys IEncodeClojure)

js (link: "null")

cljs.user=> (satisfies? IEncodeClojure a)
false
cljs.user=> (type a)
nil

`

0
_由hpnm_发表评论

关于`(identical? (goog/typeOf x) "object")`替代`(identical? (type x) js/Object)`怎么样?

Closure的typeOf正确地返回'null'和'array',并有一些针对浏览器的特定修复。
当前测试代码看起来少了很多,所以可能需要进行性能测试。

示例
(identical? "object" (goog/typeOf (.create js/Object nil #js {:a #js {:value 1}}))) => true
0
参考: https://clojure.atlassian.net/browse/CLJS-2408 (由alex+import报告)
...