2012-03-25 2 views
13

Sto cercando di scoprire come accedere alle proprietà degli oggetti Javascript in ClojureScript. Se conosco in anticipo il nome della proprietà, è facile. Per ottenere foo.bar Io faccio soloInterop ClojureScript

(.-bar foo) 

C'è un modo per accedere a una proprietà il cui nome è noto solo in fase di esecuzione? Sto cercando l'equivalente della sintassi JS foo[dynamicBar]

risposta

19

È possibile utilizzare aget/aset per accedere a proprietà note solo in fase di esecuzione.

;; 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

Si potrebbe voler sapere che è (almeno oggi) possibile usare '(js-obj" bar "100)', evitando la necessità di js *. –

0

Utilizzando nomi di stringa può essere importante anche nel caso in cui si vuole usufruire di: ottimizzazioni: modalità compilatore avanzate, ma non si dispone di un file gli esterni che coprono il codice.

esempio See David Nolen utilizzando goog.object.get: https://github.com/clojure/clojurescript/wiki/Dependencies#using-string-names

Mentre aget opere. In origine questo metodo doveva fornire l'accesso agli elementi dell'array, non alle proprietà degli oggetti js in generale. Il metodo get di goog.object è un modo migliore per comunicare il tuo intento.

Ecco le implementazioni di entrambi i metodi: 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

Come si può vedere, (aget o key) genera codice javascript o[key] direttamente, ma goog.object.get chiama un metodo che prima controlla se la chiave è presente in o.

+0

IMHO che utilizza goog.object.get direttamente è un anti-pattern in clojurescript. Rende il codice più brutto. Se il controllo è voluto è abbastanza facile da inserire senza questo. Se è generalmente ricercato, probabilmente aget dovrebbe farlo o avere un parametro opzionale per farlo. O si può semplicemente rotolare il proprio. La maggior parte delle cose è preferibile a mettere brutti nomi completi di chiusura dappertutto. –