2012-03-25 12 views
13

Estoy tratando de averiguar cómo acceder a las propiedades de objetos Javascript en ClojureScript. Si sé de antemano el nombre de la propiedad, eso es fácil. Para obtener foo.bar acabo de hacerClojureScript interop

(.-bar foo) 

¿Hay una manera de acceder a una propiedad, cuyo nombre sólo se conoce en tiempo de ejecución? Busco el equivalente de la sintaxis de JS foo[dynamicBar]

Respuesta

19

Puede utilizar aget/aset acceder a las propiedades conocidas solamente en tiempo de ejecución.

;; Use clj->js to convert clj(s) map to javascript. 
;; Note the #js {:bar 100} reader literal indicating a js map. 

cljs.user> (def foo (clj->js {:bar 100})) 
#js {:bar 100} 
cljs.user> (.-bar foo) 
100 
cljs.user> (aget foo "bar") 
100 
cljs.user> (aset foo "baz" 200) 
200 
cljs.user> (.-baz foo) 
200 
+1

Uno podría querer saber que es (al menos hoy) posible usar '(js-obj" bar "100)', evitando la necesidad de js *. –

0

El uso de nombres de cadena puede ser también importante en caso de que usted quiere tomar ventaja de: optimizaciones: modo compilador avanzada, pero no tiene el archivo externs cubriendo su código.

el ejemplo de David Nolen Ver usando goog.object.get: https://github.com/clojure/clojurescript/wiki/Dependencies#using-string-names

Mientras que aget obras. Originalmente, se suponía que este método proporcionaba acceso a los elementos de la matriz, no a las propiedades de los objetos js en general. El método get de goog.object es una mejor manera de comunicar su intención.

Estas son las implementaciones de ambos métodos: https://github.com/google/closure-library/blob/1b8a893271d790626b5cd652b922675c987f106d/closure/goog/object/object.js#L403

https://github.com/clojure/clojurescript/blob/d2d031605b1ad552077218c8f445868653c01744/src/main/clojure/cljs/core.cljc#L942

Como se puede ver, la generación de JavaScript (aget o key) código o[key] directamente, sino goog.object.get llama a un método que primero comprueba si la clave está presente en o.

+0

En mi humilde opinión, el uso de goog.object.get directamente es un anti-patrón en clojurescript. Hace un código más feo. Si se quiere el cheque, es fácil ponerlo sin esto. Si generalmente se quiere, entonces podría decirse que aget debería hacer eso o tener un parámetro opcional para hacer eso. O uno puede simplemente rodar uno propio. Casi todo es preferible a poner nombres completos de feo cierre por todas partes. –