我想實現與ClojureScript的功能,以簡化js/console.log
這樣的:JS /的console.log在ClojureScript
(defn log [& args]
(apply js/console.log args))
調用它:(log "foo" "bar")
拋出:TypeError: Illegal invocation
但這個工程:(js/console.log "foo" "bar")
問題是什麼?
我想實現與ClojureScript的功能,以簡化js/console.log
這樣的:JS /的console.log在ClojureScript
(defn log [& args]
(apply js/console.log args))
調用它:(log "foo" "bar")
拋出:TypeError: Illegal invocation
但這個工程:(js/console.log "foo" "bar")
問題是什麼?
js/something
用於訪問js對象,但不應該在此之後嵌套點,因爲它不是clojure兼容語法,它將被刪除。在舊版本的編譯器(2138)中,代碼可以工作,但在新版本的編譯器中可能已被棄用。你正在使用哪個版本?
正確的方法是使用簡單的JS互操作是這樣的:[警告:看到大衛·諾倫,ClojureScript首席開發下方評論]
(defn log [& args] (apply (.-log js/console) args))
甚至更短,因爲執行console.log已經是可變參數(只別名):
(def log (.-log js/console))
如果您首先將它放在文件頂部(enable-console-print!),也可以使用println。
他們不是完全一樣的東西。 'println'使用clojure的字符串序列化行爲,而大多數瀏覽器中的'console.log'會將對象渲染爲可導航的樹。 – eyelidlessness
我發現實際答案
(.apply (.-log js/console) js/console (clj->js args))
這是給你的功能一個工作代碼(與[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)
這裏是一篇文章,描述爲什麼(應用...)不能很好地使用JS函數。 http://clojurescriptmadeeasy.com/blog/how-to-apply-with-the-console-api.html
與console.log
使用宏而不是函數是有意義的。如果您將log
作爲一項功能實施,則所有消息都將使用您定義的log
功能的行號進行記錄。
宏解決了編譯過程中產生內嵌代碼這個問題,是要明白,宏在編譯時運行是非常重要的。
在macros.cljc
定義該宏:
(ns test.macros)
(defmacro log
[& msgs]
`(.log js/console [email protected]))
'
或quote
但:
~
或unquote
來插入評估表單,如我爲msgs
添加@
來解包多個參數:[email protected]
。有關更多信息syntax quote。然後從core.cljs
稱之爲:
(ns test.core
(:require-macros [test.macros :refer [log]]))
(log "foo" "bar")
這是完全正常的寫'JS/console.log'這是支持,永遠不會改變。無論如何,這往往會出現在互操作的情況下,所以無論如何它都是不可移植的。 – dnolen