2015-12-23 116 views
2
(defn domready [handler] 
    (.addEventListener js/window "DOMContentLoaded" handler)) 

我借用了here的这段代码。问题是我不完全理解发生了什么。 JS互操作对我来说仍然有点神秘。Clojurescript添加一个活动监听器

  1. .addEventListener

所以这显然是一个过程调用,但它是一种通用的。这就像Clojurescript把一切物体放在一个物体中,把它拿出来,然后用它在“物体”上调用该方法。只要该“对象”具有“.addEventListener”属性,它就会调用它。那是它在做什么?为什么不使用关键字呢?像(:addEventListener domElement)这对我来说似乎更合乎逻辑。

  • js/window
  • 是什么?它是一个名称空间还是一个对象?它们是一样的吗?

  • "DOMContentLoaded"
  • 的字符串,这是熟悉的。

  • handler
  • 而且熟悉,但它具有一个this概念?并不是说我真的会错过this

    +0

    对于'this',您可以使用'this-as'宏。 –

    +1

    以下是我为教学互动而编写的教程之一http://chimeces.com/cljs-browser-repl/#/notebook/diving-into-clojurescript/file/9我希望它有帮助。我会添加一个答案,回答你的问题。 – Joaquin

    +0

    只是为了避免混淆,.addEventListener是一个方法调用。还有属性的概念,可以用.-(周期和减/短划线)访问。在OO中,我猜你会说(.method obj)在(。-property obj)访问对象中的属性/变量时运行对象方法。 –

    回答

    3

    .addEventListener

    所以这显然是一个过程调用,但它是一种通用 。这就像Clojurescript把所有在 对象中的东西都拿出来一样,然后用它来调用“对象”上的方法。 只要该“对象”具有“.addEventListener”属性,它将调用此函数 。那是它在做什么?为什么不使用关键字呢? 喜欢(:addEventListener domElement),这对我来说似乎更符合逻辑。

    你的关于这种工作方式的心智模式大多好。它在编译时的作用是将函数名称作为第一个参数的方法运行。

    (.method obj ...args)获取的转化为obj.method(...args)

    这种类型的互操作的来自于母语的Clojure。

    为什么我们有一个明确的版本调用不是Clojure惯用的函数,我认为这个想法是将本地Clojure代码与Clojure语义(不变性,对CLJ数据结构友好等)什么是与主机环境互操作(可变,对CLJ数据结构不友好等)。

    在我看来,CLJS和主机平台的语义有多么不同,最好在这两者之间有明确的区分。对我而言,在这种情况下,显式性比隐含式更好(很容易发现代码在CLJS中什么是JS代码,什么是纯CLJS)。

    js/window

    这是什么?它是一个名称空间还是一个对象?它们是一样的吗?

    两者,js/正在访问的命名空间js,这是在CLJS放JS命名空间(因为仅存在一个和全局)。 window仅抓取js命名空间的window变量。

    这与您如何访问CLJS中其他名称空间中的变量没有区别。如果你在(ns cljs.test)然后运行cljs.test/a那会给你1。相同的形式,ns/something-in-that-ns

    "DOMContentLoaded" 字符串,这很熟悉。

    \ O/

    handler

    也比较熟悉,但它有这样一个概念?不是我真的会想念这个。

    不知道thishandler有什么关系。这仅仅是一个高阶函数传入domready作为参数,就像你在JS做:function domready (onReady) { window.addEventListener("DOMContentLoaded", onReady) }


    我希望这可以帮助,如果你想尝试一下现场,了解更多一些,也许访问Talking with JSDiving into ClojureScript教程,或者查看这个section of the lt-cljs-tutorial

    +0

    谢谢你这么棒的答案! – Breedly

    1

    .addEventListener是调用全局Javascript对象js/window的方法。此方法调用需要两个参数:"DOMContentLoaded"handler

    当你在做互操作(Java或Javascript)时,你确实在调用对象的方法。这里发生的事情背后有宏。 (是一个动词,我通常认为它是一个函数调用(尽管它也可能是一个宏或一种特殊的形式)。在互动过程中,动词是实例之后,之后是参数。

    如果是直接的JavaScript它应该是这样的:

    function domready(handler){ 
        window.addEventListener("DOMContentLoaded" handler); 
    } 
    
    0

    我刚学clojurescript所以我真的不知道这是否是正确的答案,但我在下面的方式来完成它:

    (defn handler [] (js/console.log "ready")) 
    (js/document.addEventListener "DOMContentLoaded" handler) 
    

    ,然后将其转换为

    cljs.user.handler = (function cljs$user$handler(){ 
        return console.log("ready"); 
    }); 
    document.addEventListener("DOMContentLoaded",cljs.user.handler); 
    

    检查clojurescript如何翻译我使用的代码KLIMPSE http://app.klipse.tech/