在Clojurescript中,如何将集合的元素作为参数传递给变量arity Javascript函数?

时间:2016-12-16 18:58:27

标签: interop clojurescript

这会以我期望的方式写入控制台:

(.log js/console "hi" "there")

输出

hi there

然而,这只是给控制台写了一个大麻烦:

(defn log-it [& args] (.log js/console args))
(log-it "hello" "there")

输出结果为:

c…s.c…e.IndexedSeq {arr: Array[2], i: 0, meta: null, cljs$lang$protocol_mask$partition0$: 166592766, cljs$lang$protocol_mask$partition1$: 8192}

这也不起作用:

(apply .log js/console ["hi" "there"])

有没有办法将vector的元素传递给.log函数? 我是否必须编写一个宏来将向量连接到'(.log js/console)

1 个答案:

答案 0 :(得分:2)

这里的问题是你试图记录args(这是一个Clojure IndexedSeq)的值,而不是将seq中的值作为单独的参数传递。在这种情况下,您需要使用apply(或将该序列转换为本机数据结构)。

如果你看the signature for apply,你的其他例子不起作用的原因应该变得清晰。

(apply f args)

它希望第一个参数是你想要调用的函数,但是在这里,第一个参数是.log

(apply .log js/console ["hi" "there"])

请记住,.log js/console是在log上调用console方法的语法。相反,我们希望获得对console.log函数的引用。

(apply (.-log js/console) args)

我们正在使用.-log来阅读.log属性,而不是将其称为方法。然后我们将其与args序列一起传递。

相反,您可以将原始函数定义为:

(defn log-it
  [& args]
  (apply (.-log js/console) args))

或者如果你想变得更聪明一点。

(def log-it (partial (.-log js/console)))