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
by

评论者:kurtharriger

上述内容还暗示或许可以扩展IEncodeClojure到nil?
a不是nil,但它的类型是...所以可能扩展到nil上的协议应该会起作用?

但不起作用...这可能是在satisfies?中的一个错误?

`
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)

对象(link: Object)

cljs.user=> (js-keys IEncodeClojure)

js (link: "null")

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

`

0
by
_由: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
by
参考:https://clojure.atlassian.net/browse/CLJS-2408 (由alex+import报告)
...