将JavaScript对象转换为ClojureScript:Getter和Setter属性

将JavaScript对象转换为ClojureScript:Getter和Setter属性,javascript,clojure,clojurescript,Javascript,Clojure,Clojurescript,我正在努力解决以下问题: 通常JS对象通过JS->clj转换为ClojureScript。 这适用于原型对象的对象。 对于另一个,我正在使用: (defn jsx->clj [o] (reduce (fn [m v] (assoc m (keyword v) (aget o v))) {} (.keys js/Object o))) 我发现,“属性”,即幕后的getter函数,不能通过这些操作进行转换 有人有过这样的经历吗?我不知道你说的“幕后的getter函数无法通过这些操作进行

我正在努力解决以下问题:

通常JS对象通过JS->clj转换为ClojureScript。 这适用于原型对象的对象。 对于另一个,我正在使用:

(defn jsx->clj [o]
  (reduce (fn [m v] (assoc m (keyword v) (aget o v)))  {} (.keys js/Object o)))
我发现,“属性”,即幕后的getter函数,不能通过这些操作进行转换


有人有过这样的经历吗?

我不知道你说的“幕后的getter函数无法通过这些操作进行转换”是什么意思

其中一个问题是,当您像这样将JS对象转换为CLJS映射时,getter和setter将不会绑定到原始JS对象,因此它们将无法访问此对象的属性

考虑以下代码:

;; This is your function, no changes here.
(defn jsx->clj [o]
  (reduce (fn [m v] (assoc m (keyword v) (aget o v)))  {} (.keys js/Object o)))


;; This is an improved version that would handle JS functions that
;; are properties of 'o' in a specific way - by binding them to the
;; 'o' before assoc'ing to the result map.
(defn jsx->clj2 [o]
  (reduce (fn [m v]
            (let [val (aget o v)]
              (if (= "function" (goog/typeOf val))
                (assoc m (keyword v) (.bind val o))
                (assoc m (keyword v) val))))
          {} (.keys js/Object o)))

;; We create two JS objects, identical but distinct. Then we convert
;; both to CLJS, once using your function, and once using the improved
;; one.
;; Then we print results of accessing getter using different methods.
(let [construct-js (fn [] (js* "new (function() { var privProp = 5; this.pubProp = 9; this.getter = function(x) { return privProp + this.pubProp + x; }; })"))
      js-1 (construct-js)
      js-2 (construct-js)
      clj-1 (jsx->clj js-1)
      clj-2 (jsx->clj2 js-2)]
  (.log js/console "CLJS objects: " (.getter js-1 10) ((:getter clj-1) 10) (.getter js-2 10) ((:getter clj-2) 10)))
这张照片是:

CLJS objects:  24 NaN 24 24
这意味着以下代码:
(:getter clj-1)10
失败,而
(:getter clj-2)10
按预期工作。第二个是有效的,因为它被用来正确地将函数与JS对象绑定在一起

如果这确实是您失败的原因,那么这个问题相当于JS中有时出现的以下错误:

var Constructor = function() {
  var privProp = 5;
  this.pubProp = 9;
  this.getter = function(x) {
    return privProp + this.pubProp + x;
  };
}
var obj1 = new Constructor();
var obj2 = new Constructor();
var fn1 = obj1.getter;             // Invalid, fn1 will not be bound to obj1.
var fn2 = obj2.getter.bind(obj2);  // Note .bind here.
console.log(fn1(10), fn2(10));
打印类似输出的:

NaN 24

同样,未绑定到
obj1
fn1
返回无效输出。

如果您直接使用试剂或试剂包装或Om,则互操作将最小化。大多数使用Clojurescript的人使用这些Facebook React包装器之一。因此,很少有人会有“这方面的经验”。