CLJS:将 JS 属性 设置为对其调用方法的结果

CLJS: Setting a JS property to the result of calling a method on it

我想修改 Web 应用程序中的一些现有文本,我正在使用如下表达式访问这些文本:

(.-innerHTML (.getElementById js/document "myElementId"))

我特别想做的是通过 search/replace:

改变该文本
(set! (^that whole thing) (.replace (^that whole thing) "old" "new"))

而且我希望不必重复 属性-access 表达式就可以做到这一点。有没有现成的捷径?我正在设想像 Raku 的 object .= method(args) shorthand for object = object.method(args) 这样的东西;也许一个好的 clj name/pattern 会是 (.set! (access-expression) method & args)。我总能写一个宏,但想知道我是否忽略了一些已经存在的东西。

我也很好奇,于是查看了 CLJS CheatSheet and they link to the CLJS Oops 库,它提供了类似的功能。

似乎最可靠的解决方案是仅依赖 Google 闭包库(它总是在手边)并结合使用 goog.object/getgoog.object/set(不需要宏),例如:


(require 'goog.object)

(defn update-obj! [obj field f & args]
  (let [old-val (goog.object/get obj field)
        new-val (apply f old-val args)]
    (goog.object/set obj field new-val)))

;; Example:
(update-obj! (.getElementById js/document "my-div") "innerHTML" (partial str "it works: "))

这应该适用于开发和优化输出。