你能解构 ClojureScript 中的 JavaScript 对象吗?
Can you destructure a JavaScript Object in ClojureScript?
我想知道是否有办法让 ClojureScript 解构与 JavaScript 对象一起工作,例如:
(let [{:keys [a b]} #js{:a 10, :b 20}]
(print a) ;=> I get nil, but I'd want to get 10
(print b)) ;=> I get nil, bu I'd want to get 20
谢谢
我还没有找到直接解构 JS 对象的方法。您可以将 JavaScript 对象转换为 ClojureScript 数据结构,然后解构:
(let [{:keys [a b]} (js->clj #js {:a 10 :b 20}
:keywordize-keys true)]
(print a)
(print b))
如果你在 js->clj
中不使用 :keywordize-keys
选项,你需要在解构
中使用 strs
而不是 keys
(let [{:strs [a b]} (js->clj #js {:a 10 :b 20})]
(print a)
(print b))
关联解构基于 get
,可以将 JavaScript 对象映射到 goog.object/get
,方法是将它们扩展到 ILookup
:
(extend-type object
ILookup
(-lookup
([o k]
(goog.object/get o (name k)))
([o k not-found]
(goog.object/get o (name k) not-found))))
尽管这会导致对 JavaScript 对象进行解构,但不建议以这种方式扩展 object
。最好装饰一个对象实例来达到类似的效果。
这是一个使用 reify
的例子:
(defn wrap [o]
(reify
ILookup
(-lookup [_ k]
(goog.object/get o (name k)))
(-lookup [_ k not-found]
(goog.object/get o (name k) not-found))))
与上面定义的wrap
:
(let [{:keys [a b]} (wrap #js{:a 10, :b 20})]
(print a)
(print b))
库中提供类似 wrap
功能的函数包括:
lookup
在 js-interop
bean
在 CLJS Bean
Matt Huebert 的 js-interop library provides JavaScript object destructuring 及其版本 let
开箱即用。你所要做的就是在绑定形式前添加^:js
:
(ns foo.bar
(:require [applied-science.js-interop :as j]))
(j/let [^:js {:keys [a b]} #js{:a 10, :b 20}]
[a b])
;; => [10 20]
这适用于递归(有一个逃生舱口,^:clj
)并且在 j/fn
和 j/defn
中也有效。如果 ^:js
被省略,这些函数就像普通的 Clojure 一样。
我想知道是否有办法让 ClojureScript 解构与 JavaScript 对象一起工作,例如:
(let [{:keys [a b]} #js{:a 10, :b 20}]
(print a) ;=> I get nil, but I'd want to get 10
(print b)) ;=> I get nil, bu I'd want to get 20
谢谢
我还没有找到直接解构 JS 对象的方法。您可以将 JavaScript 对象转换为 ClojureScript 数据结构,然后解构:
(let [{:keys [a b]} (js->clj #js {:a 10 :b 20}
:keywordize-keys true)]
(print a)
(print b))
如果你在 js->clj
中不使用 :keywordize-keys
选项,你需要在解构
strs
而不是 keys
(let [{:strs [a b]} (js->clj #js {:a 10 :b 20})]
(print a)
(print b))
关联解构基于 get
,可以将 JavaScript 对象映射到 goog.object/get
,方法是将它们扩展到 ILookup
:
(extend-type object
ILookup
(-lookup
([o k]
(goog.object/get o (name k)))
([o k not-found]
(goog.object/get o (name k) not-found))))
尽管这会导致对 JavaScript 对象进行解构,但不建议以这种方式扩展 object
。最好装饰一个对象实例来达到类似的效果。
这是一个使用 reify
的例子:
(defn wrap [o]
(reify
ILookup
(-lookup [_ k]
(goog.object/get o (name k)))
(-lookup [_ k not-found]
(goog.object/get o (name k) not-found))))
与上面定义的wrap
:
(let [{:keys [a b]} (wrap #js{:a 10, :b 20})]
(print a)
(print b))
库中提供类似 wrap
功能的函数包括:
lookup
在 js-interopbean
在 CLJS Bean
Matt Huebert 的 js-interop library provides JavaScript object destructuring 及其版本 let
开箱即用。你所要做的就是在绑定形式前添加^:js
:
(ns foo.bar
(:require [applied-science.js-interop :as j]))
(j/let [^:js {:keys [a b]} #js{:a 10, :b 20}]
[a b])
;; => [10 20]
这适用于递归(有一个逃生舱口,^:clj
)并且在 j/fn
和 j/defn
中也有效。如果 ^:js
被省略,这些函数就像普通的 Clojure 一样。