Подтвердить что ты не робот

ClojureScript interop

Я пытаюсь выяснить, как получить доступ к свойствам объектов Javascript в ClojureScript. Если я заранее знаю название собственности, это легко. Чтобы получить foo.bar, я просто делаю

(.-bar foo)

Есть ли способ получить доступ к свойству, имя которого известно только во время выполнения? Я ищу эквивалент синтаксиса JS foo[dynamicBar]

4b9b3361

Ответ 1

Вы можете использовать aget/aset для доступа к свойствам, известным только во время выполнения.

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

Ответ 2

Использование имен строк также может быть важно в том случае, если вы хотите воспользоваться преимуществами: оптимизация: расширенный режим компилятора, но у вас нет файла externs, охватывающего ваш код.

См. пример Дэвида Нолена с помощью goog.object.get: https://github.com/clojure/clojurescript/wiki/Dependencies#using-string-names

Пока работает aget. Первоначально этот метод предоставлял вам доступ к элементам массива, а не к свойствам объектов js в целом. Метод goog.object get - лучший способ сообщить о ваших намерениях.

Вот реализация обоих методов: 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

Как вы можете видеть, (aget o key) напрямую генерирует javascript-код o[key], но goog.object.get вызывает метод, который сначала проверяет, присутствует ли ключ в o.