ClojureScript中的js / console.log

时间:2014-06-16 08:10:37

标签: debugging clojurescript

我想用ClojureScript实现一个函数来简化js/console.log,如下所示:

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

致电:(log "foo" "bar") 抛出:TypeError: Illegal invocation

但这可行:(js/console.log "foo" "bar")

有什么问题?

6 个答案:

答案 0 :(得分:12)

js/something用于访问js对象,但在此之后你不应该嵌套点,因为它不是与clojure兼容的语法,它将被删除。在旧版本的编译器(2138)中,您的代码可以正常工作,但有可能在较新版本的编译器中不推荐使用它。你使用的是哪个版本?

正确的方法是使用这样简单的js互操作:[警告:请参阅以下评论来自David Nolen,ClojureScript首席开发人员]

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

甚至更短,因为console.log已经是variadic(只是做一个别名):

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

答案 1 :(得分:6)

如果您首先将它放在文件的顶部,也可以使用println :( enable-console-print!)。

答案 2 :(得分:6)

pprint已被移植:

:require [cljs.pprint :refer [pprint]]

答案 3 :(得分:3)

我找到了实际答案

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

答案 4 :(得分:2)

以下是您的函数的工作代码(使用[org.clojure / clojurescript“1.7.228”测试]):

; working
(defn log [& args]
  (.apply js/console.log js/console (to-array args)))

; not working
; (defn log [& args] (apply (.-log js/console) args))
; (defn log [& args] (apply js/console.log args))
; (def log js/console.log)

这篇文章描述了为什么(apply ...)与JS函数不兼容。 http://clojurescriptmadeeasy.com/blog/how-to-apply-with-the-console-api.html

答案 5 :(得分:1)

console.log使用宏而不是函数是有意义的。如果您将log实现为函数,则将使用您log函数定义的行号记录所有消息。

宏通过在编译期间生成内联代码来解决此问题,了解宏在编译时运行非常重要。

macros.cljc中定义此宏:

(ns test.macros)

(defmacro log
  [& msgs]
  `(.log js/console ~@msgs))
  • `:与'quote类似,但是:
    • 符号会自动解析为包含其名称空间,以防止在评估时出现含糊不清的符号。
    • 可以使用~unquote插入评估表单,就像我msgs添加@以解压缩多个参数一样:~@msgs。有关syntax quote
    • 的更多信息

然后从core.cljs

调用它
(ns test.core
  (:require-macros [test.macros :refer [log]]))

(log "foo" "bar")