我想用ClojureScript实现一个函数来简化js/console.log
,如下所示:
(defn log [& args]
(apply js/console.log args))
致电:(log "foo" "bar")
抛出:TypeError: Illegal invocation
但这可行:(js/console.log "foo" "bar")
有什么问题?
答案 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")