Jos*_*h.F 3 clojure clojurescript
我正在调试一些代码,并将我的问题归结为一个简单的示例:
(js/console.log (.-hey (clj->js {:hey "please work!"})))
Run Code Online (Sandbox Code Playgroud)
印刷undefined
它一定与高级优化期间的重命名有关,但我不知道发生了什么,也不知道如何修复它......
如果您使用在线 CLJS REPL,例如http://clojurescript.net/,它会按预期工作(返回nil但打印please work!),但在使用高级优化下cljsbuild,它根本不起作用!
嗯,知道我哪里搞砸了吗?
编辑:
经过进一步反思,以及 clojurians 关于 slack 的一些建议,我认为,这是因为当我使用clj->js.
我发现我(认为)我需要这样做,因为我正在尝试与 D3.js 库(来自 cljsjs)进行互操作,并且当我传递它的东西时,它期待的是js对象,而不是cljs对象。是否有一种惯用的方法将 cljs 对象传递到您正在交互的 js 库?(如果这确实是我的问题?)
使用高级优化编译时,您的代码将无法工作。您可以检查它比较使用不同优化设置编译的版本。
生成 JS 对象的部分工作正常,例如以下内容将工作:
(.log js/console (clj->js {:hey "please work"}))
Run Code Online (Sandbox Code Playgroud)
将产生
Object {hey: "please work"}
Run Code Online (Sandbox Code Playgroud)
但是访问属性的部分hey将在使用高级优化的编译过程中中断。
当你编译时
(.log js/console (.-hey (clj->js {:hey "please work"})))
Run Code Online (Sandbox Code Playgroud)
你会得到类似的东西:
和optimizations :none:
console.log(
cljs.core.clj__GT_js.call(
null,new cljs.core.PersistentArrayMap(null, 1,
[new cljs.core.Keyword(null,"hey","hey",301812684),"please work"], null)
).hey);
Run Code Online (Sandbox Code Playgroud)
和optimizations :advanced:
console.log(Tg(new jb(null,1,[Nh,"please work"],null)).ci);
Run Code Online (Sandbox Code Playgroud)
请注意属性键是如何.hey被破坏成.ci. 这是因为 Google Closure 在优化阶段对其进行了重命名(为了节省结果 JS 文件中的空间,它用较短的标识符替换了名称)。"hey"对象中的字符串不会被破坏,因为它是字符串文字,并且您会得到不一致的结果。
当您将结果传递clj->js给外部函数(例如在 d3js 中)时,您的代码应该按预期工作,因为如果您使用带有 externs 文件的缩小版本,则外部库不会被破坏(请参阅 @Andre 对您的问题的评论和CLJS 文档)部门和外部人员。)
当您需要访问示例中的此类属性并需要它进行高级优化时,您可以使用goog.object/get或如docgoog.object/getValueByKeys中所述。cljs.core/aget