我正在寻找一种在ClojureScript中通过函数名字符串来调用函数的方法。
例如:
例如:
(call "my-fun" args)
Any help welcome
(call "my-fun" args)
Any help welcome
一种相当搞怪的解决方法:
(ns eval.core
(:require [clojure.string :as str]))
(defn ->js [var-name]
(-> var-name
(str/replace #"/" ".")
(str/replace #"-" "_")))
(defn invoke [function-name & args]
(let [fun (js/eval (->js function-name))]
(apply fun args)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Usage:
(ns example.core
(:require [eval.core :as e]))
(defn ^:export my-fn [arg1 arg2] ;; Note the export!
(println arg1 arg2)
arg2)
(e/invoke "example.core/my-fn" 5 6) ;=> 5 6
我需要一种调用动态加载ns/name函数的方法。如前所述,没有受支持的方法可以做到这一点。然而,这就是hack存在的目的。这是我最终采取的方法:
调用cljs:
(js/proxy "my-ns/my-fun" args)
Proxy.js:
function proxy() {
var args = Array.prototype.slice.call(arguments);
var nsFunc = args[0].replace(/-/g, "_").replace(/\//g, ".");
eval(nsFunc).apply(null, args.slice(1));
}
动态解析 cljs:
(ns my-ns)
(defn ^:export my-fun [args] ...)
(def global (this-as this this))
(defn call [fname & args]
(.apply (aget global fname) global args))
(call "String" 123)
global
绑定到全局作用域中使用this
运算符的全局对象,可以在任何平台上使用。您可以使用.call
替代.apply
,例如:
(.call (aget global "String") global 123)