Philippa Markovics / Jun 13 2019
Inheritance in JavaScript & ClojureScript
ES 6
ES 6 brings the class
keyword for defining classes. extends
can be used to inherit parent properties and super
for calling parent methods withing the child’s scope.
class CodeMirrorView { constructor (el, lang) { this.el = el; this.lang = lang; this.editor = new CodeMirror(el, { mode: lang }); } update (node) { this.node = node; return true; } } class CodeListingView extends CodeMirrorView { constructor (el, lang) { super(el, lang); const header = document.createElement("header"); this.el.appendChild(header); } }
JavaScript
ES 5
To achieve the same effect in ES 5 we have to set the child’s prototype to the parent’s. Calling the child’s constructor will extend upon the parent’s prototype. To use parent methods, we will have to call them from the parent’s prototype and set the call scope explicitly to the current scope (this
).
function CodeMirrorView(el, lang) { this.el = el; this.lang = lang; this.editor = new CodeMirror(el, { mode: lang }); } CodeMirrorView.prototype.update = function(node) { this.node = node; return true; } function CodeListingView(el, lang) { CodeMirrorView.call(this, el, lang); const header = document.createElement("header"); this.el.appendChild(header); } CodeListingView.prototype = Object.create(CodeMirrorView.prototype); CodeListingView.constructor = CodeListingView;
JavaScript
ClojureScript
This mimics pretty much what’s going on in ES 5 because there are no macros for using the native ES 6 class
, extends
and super
keywords. There is a discussion on the cljs JIRA regarding this.
(defn CodeMirrorView [el lang] (this-as this (set! (.-el this) el) (set! (.-lang this) lang) (set! (.-editor this) (js/CodeMirror. el js {:mode lang})))) (set! (.. CodeMirrorView -prototype -update) (fn [node] (this-as this (set! (.-node this) node)))) (defn CodeListingView [el lang] (this-as this (.call CodeMirrorView this el lang) (let [header (js/document.createElement "header")]) (set! (.-header this) header))) (set! (.. CodeListingView -prototype) (js/Object.create (.-prototype CodeMirrorView))) (set! (.. CodeListingView -prototype -constructor) CodeListingView)
ClojureScript