-
Notifications
You must be signed in to change notification settings - Fork 8
Examples
Please note that the output from the following examples are pretty printed Javascript, which is not the default.
To get started:
(use 'clojurejs.js)
For a more detailed (lightly tested) example of using ClojureJS, check out the following gist:
https://gist.github.com/788487
(js
(defn test-fn [a]
(let [b (+ a 1)
c (+ b 1)]
(+ a b c))))
translates to the following Javascript:
test_fn = function (a) {
var
b = (a + 1),
c = (b + 1);
return (a + b + c);;
}
Function args and let bindings can be destructured, e.g.:
(js
(defn test-fn [num-list]
(let [ [a b] num-list
c (+ b 1)]
(+ a b c))))
which translates to:
test_fn = function (num_list) {
var
_temp_1000 = num_list, a = _temp_1000[0], b = _temp_1000[1],
c = (b + 1);
return (a + b + c);;
}
Map destructuring (aka associative destructuring) allows to bind the properties of a JavaScript object to names, including :keys
syntax and defaults for missing keys (using :or
). For example:
(js
(defn test-fn [square]
(let [{:keys [x1 y1 x2 y2]} square
area (* (- x2 x1) (- y2 y1))]
(do-stuff area))))
becomes:
test_fn = function (square) {
var
_temp_1000 = square,
x1 = _temp_1000['x1'], x2 = _temp_1000['x2'],
y1 = _temp_1000['y1'], y2 = _temp_1000['y2'],
area = ((x2 - x1) * (y2 - y1));
return do_stuff(area);;
When destructuring an array, aliasing the whole array with :as
works the same as in Clojure. Destructuring bindings may be nested arbitrarily.
(js
(defmacro nil? [x] `(== nil ~x))
(if (nil? a) (print "is null")))
translates to the following Javascript:
if ((null == a)) { print("is null"); };
(js
(defn join [arr delim]
(loop [str (get arr 0)
i 1]
(if (< i (length arr))
(recur (+ str delim (get arr i))
(+ i 1))
str))))
translates to the following Javascript:
join = function (arr, delim) {
for (var str = arr[0], i = 1; true;) {
if ((i < arr.length)) {
str = (str + delim + arr[i]);
i = (i + 1);
continue;
} else {
return str;
};
break;
};
}
(js
(defn test []
(try
(/ 5 0)
(catch ex
(console.log ex))
(finally
0))))
translates to:
test = function() {
try {
return (5 / 0);
} catch (ex) {
return console.log(ex);
} finally {
return 0;
};
}
The defn
form doesn't support multiple arity forms or keyword args. Doc-strings are supported and emitted as comments if pretty-printing is turned on.
Currently, there's no support for namespaces. Macro expanders are defined in a global ref, which is preserved between successive invocations of the translator.
There's lots of room for improvements in the generated Javascript, from performance tweaks to better formatting of expressions.
The file `boot.cljs' includes some useful macros and utility functions implemented in ClojureJS.
The html function in boot.cljs implements a minimal HTML templating facility which is similar to hiccup, but is executed on the browser side.
(jq
(defn test []
(.append ($ document.body)
(html
[:div {:id "container"}
[:span {:class "title"} "Lorem ipsum blah blah"]
[:ul {:id "hmenu"}
[:li [:a {:class "link_login"} "Login"]]
[:li [:a {:class "link_signup"} "Signup"]]
[:li [:a {:class "link_about"} "About"]]
[:li [:a {:class "link_contact"} "Contact"]]]]))))
Invoking (test) on the browser side would create and add the dom tree specified in the array structure to the document body.
The html-str
function is similar to the html
function, except it returns a HTML string representation of the specified spec
. e.g.,
(html-str
[:ul
[:li [:a {:href "#"} "link1"]]
[:li [:a {:href "#"} "link2"]]])
at runtime, would generate:
"<ul><li><a href='#'>link1</a></li><li><a href='#'>link2</a></li></ul>"