(defn domready [handler]
(.addEventListener js/window "DOMContentLoaded" handler))
我从 here 借用了这段代码。问题是我不完全明白发生了什么。 JS 互操作对我来说仍然有点神秘。
.addEventListener
所以这显然是一个过程调用,但它是通用的。这就像 Clojurescript 取出对象内部的所有内容,取出它,然后使用它在“对象”上调用该方法。只要该“对象”具有“.addEventListener”属性,它就会调用它。这是它在做什么?为什么不改用关键字?像
(:addEventListener domElement)
对我来说似乎更合乎逻辑。js/window
这是什么?它是命名空间还是对象?它们是一样的吗?
"DOMContentLoaded"
一个字符串,很熟悉。
handler
也很熟悉,但它有
this
的概念吗?并不是说我真的会想念 this
。
最佳答案
.addEventListener
So this is clearly a procedure call, but it's kind of generic. It's like Clojurescript took everything that was inside an object, took it out, and you use it to call that method on "objects". As long as that "object" has the ".addEventListener" property it will call this. Is that what it's doing? Why not use a keyword instead? like (:addEventListener domElement) that seems more logical to me.
你关于它是如何工作的心理模型大多是好的。它在编译时所做的是将函数名称作为第一个参数上的方法运行。
(.method obj ...args)
转换为 obj.method(...args)
这种类型的互操作来自父语言 Clojure。
关于为什么我们有一个显式版本的调用不是 Clojure 惯用的函数,我认为这个想法是在什么是具有 Clojure 语义的本地 Clojure 代码(不变性、对 CLJ 数据结构友好等)和什么是互操作之间有明确的区别与主机环境(可变,对 CLJ 数据结构不友好等)。
在我看来,鉴于 CLJS 和主机平台的语义有多么不同,最好将这两者明确分开。对我来说,在这种情况下,显式比隐式更好(通过查看代码很容易发现什么是 CLJS 中的 JS 代码,什么是纯 CLJS)。
js/window
What is this? Is it a namespace or an object? Are they the same thing?
两者,
js/
都在访问命名空间 js
,这是 CLJS 放置 JS 命名空间的地方(因为只有一个并且是全局的)。 window
只是从 js 命名空间中获取 window
变量。这与您在 CLJS 中访问其他命名空间中的变量的方式没有什么不同。如果您在
(def a 1)
中输入 (ns cljs.test)
,然后运行 cljs.test/a
,它将为您提供 1
。相同的形式, ns/something-in-that-ns
。
"DOMContentLoaded"
A string, that's familiar.
\o/
handler
Also familiar, but does it have a notion of this? Not that I'm really going to miss this.
不确定
this
与 handler
有什么关系。它只是一个作为参数传递给 domready
的高阶函数,就像你在 JS 中所做的那样: function domready (onReady) { window.addEventListener("DOMContentLoaded", onReady) }
我希望这会有所帮助,如果您想实时试用并了解更多信息,请访问 Talking with JS 教程中的 Diving into ClojureScript ,或者查看此 section of the lt-cljs-tutorial 。
关于Clojurescript 添加事件监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34428624/