Я хочу написать программу, которая добавляет сложное поведение в div (например, подумайте о какой-то интерактивной графике). Я хотел бы иметь возможность передать div функции в библиотеке и добавить библиотеку в div.Что такое эквивалент ClojureScript области видимости JavaScript с аргументом
Если бы я делал это в JavaScript, я бы написал следующее.
В my_page.html
:
<div id="program-container"></div>
<script src="my_library.js" type="text/javascript"></script>
<script type="text/javascript">
useDivForACoolProgram(document.getElementById("program-container"));
</script>
В my_library.js
:
function useDivForACoolProgram(div) {
var x = 2;
var y = 3;
function setup() {
div.innerHTML = "Getting ready to run...";
doMainSetup();
}
function doMainSetup() {
...
// Lots more functions, many of which refer to div
}
Обратите внимание, что библиотека предоставляет одну функцию которая принимает DIV. Когда мы передаем ему div, библиотека сохраняет все свое состояние в закрытии, связанном с переданным div, что потенциально позволило бы мне добавить это поведение ко многим div на странице, если бы я был настолько склонен.
Я хочу сделать то же самое в ClojureScript. Моя первая попытка была следующей:
(defn use-div-for-a-cool-program [div]
(def x 2)
(def y 3)
(defn setup []
(set! (.innerHTML div) "Getting ready to run...")
(do-main-setup))
(defn do-main-setup []
...
;; Lots more functions, many of which refer to div
)
Но это не работает, потому что def
и defn
определяют переменные в области видимости модуля, а не определение локальных переменных в use-div-for-a-cool-program
. Если бы я должен был называть use-div-for-a-cool-program
несколько раз с разными div, все новые def
s и defn
s каждый раз заменяют старые.
Вместо этого можно использовать let
, но это немного неудовлетворительно, потому что это заставляет нас выполнять реализацию функций до того, как их можно будет называть, и их также трудно читать, например.
(defn use-div-for-a-cool-program [div]
(let [x 2
y 3
do-main-setup (fn []
...)
setup (fn []
(set! (.innerHTML div) "Getting ready to run...")
(do-main-setup))
;; Lots more functions, many of which refer to div
]
(setup)))
Есть ли лучшее решение?
Мне нравится то, что вы пытаетесь сделать здесь, но предположите, что моя программа несет в себе состояние. В качестве простого примера предположим, что я хочу отслеживать, сколько раз был нажат div.Если бы я делал это с закрытием, я бы сохранил измененную переменную в закрытии, поэтому все мои функции могли бы ссылаться на нее, и каждый div автоматически получит свою собственную переменную. Где бы вы сохранили это состояние в своем примере? – dphilipson