2015-12-23 115 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/