2015-09-08 14 views
7

Sto provando a convertire un oggetto Javascript in un Clojure. Tuttavia, viene visualizzato il seguente errore:ClojureScript - converte l'oggetto JavaScript arbitrario nella mappa Clojure Script

(js/console.log (js->clj e)) ;; has no effect 
(pprint (js->clj e)) ;; No protocol method IWriter.-write defined for type object: [object Geoposition] 

Sì, questo oggetto proviene dall'API di geolocalizzazione. Suppongo di dover estendere IEncodeClojure e IWriter, ma non ho idea di come.

Per esempio per aggiungere il seguente:

(extend-protocol IEncodeClojure 
    Coordinates 
    (-js->clj [x options] 
    (println "HERE " x options))) 

produce un errore durante il caricamento il mio codice: Uncaught TypeError: Cannot read property 'prototype' of undefined

+0

Sei sicuro di avere un oggetto lì e non 'undefined'? Cosa produce '(js/console.log (indefinito? E))' rendimento? –

+0

@TimPote Non è indefinito: utilizzando il timbro Clojure, ottengo il nome dell'oggetto. Usando js/console.log ottengo lo stesso oggetto js quando faccio '(js/console.log e)' e '(js/console.log (js-> clj e))'. – nha

risposta

4

La risposta accettata non funzionava per me con l'oggetto JavaScript window.performance.timing. Questo perché Object.keys() non restituisce effettivamente gli oggetti di scena per l'oggetto PerformanceTiming.

(.keys js/Object (.-timing (.-performance js/window)) 
; => #js[] 

Questo nonostante il fatto che gli oggetti di scena di PerformanceTiming sono infatti iterabile con una vaniglia JavaScript ciclo:

for (a in window.performance.timing) { 
    console.log(a); 
} 
// navigationStart 
// unloadEventStart 
// unloadEventEnd 
// ... 

Quello che segue è quello che mi è venuta per convertire un oggetto JavaScript arbitrario ad un ClojureScript carta geografica. Nota l'uso di due semplici funzioni di Google Closure.

  • goog.typeOf avvolge typeof, che non è normalmente accessibile a noi in ClojureScript. Lo uso per filtrare i puntelli che sono funzioni.
  • goog.object.getKeys wraps for (prop in obj) {...}, creazione di un risultato di matrice che è possibile ridurre in una mappa.

Soluzione

(defn obj->clj 
    [obj] 
    (-> (fn [result key] 
     (let [v (aget obj key)] 
      (if (= "function" (goog/typeOf v)) 
      result 
      (assoc result key v)))) 
     (reduce {} (.getKeys goog/object obj))))