You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否将JavaScript方法当作ClojureScript函数使用?附日期计算代码问题

问题解答

你的报错核心原因是:在ClojureScript中,.getSeconds、.setSeconds这类写法是方法调用的语法糖,并不是可以直接赋值和调用的函数对象。直接把它们当作函数使用会导致CLJS无法正确解析,从而抛出错误。

修正方案:用匿名函数包裹方法调用

把每个unit对应的getter和setter改成匿名函数,让它们能接收date参数并执行对应的方法调用:

(defn date-add [date num unit]
  (let [[getter setter]
        (case unit
          :sec [#(.getSeconds %) #(.setSeconds %1 %2)]
          :min [#(.getMinutes %) #(.setMinutes %1 %2)]
          :hour [#(.getHours %) #(.setHours %1 %2)]
          :day [#(.getDate %) #(.setDate %1 %2)]
          :month [#(.getMonth %) #(.setMonth %1 %2)]
          :year [#(.getFullYear %) #(.setFullYear %1 %2)])]
    (setter date (+ num (getter date)))
    (js/Date. (.getTime date))))

另一种方案:从原型获取方法并绑定上下文

如果想直接使用JS方法的函数引用,需要从js/Date.prototype上获取方法,并且调用时绑定date对象作为this(因为JS方法依赖当前实例作为上下文):

(defn date-add [date num unit]
  (let [[getter setter]
        (case unit
          :sec [(. js/Date.prototype -getSeconds) (. js/Date.prototype -setSeconds)]
          :min [(. js/Date.prototype -getMinutes) (. js/Date.prototype -setMinutes)]
          :hour [(. js/Date.prototype -getHours) (. js/Date.prototype -setHours)]
          :day [(. js/Date.prototype -getDate) (. js/Date.prototype -setDate)]
          :month [(. js/Date.prototype -getMonth) (. js/Date.prototype -setMonth)]
          :year [(. js/Date.prototype -getFullYear) (. js/Date.prototype -setFullYear)])]
    (.call setter date (+ num (.call getter date)))
    (js/Date. (.getTime date))))

这种方式需要用.call来指定方法执行的上下文(即date对象),否则JS方法会因为this指向错误而失效。

补充说明

  • 第一种匿名函数的方式更符合CLJS的编写习惯,代码可读性更高,也不需要处理上下文绑定的问题。
  • 你创建新js/Date实例的做法是对的,因为JS的set*方法会修改原date对象,返回新实例可以避免副作用。

内容的提问来源于stack exchange,提问作者hata

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 16:25:05