Skip to content

Instantly share code, notes, and snippets.

@squaremo
Last active December 15, 2015 18:39
Show Gist options
  • Select an option

  • Save squaremo/5305729 to your computer and use it in GitHub Desktop.

Select an option

Save squaremo/5305729 to your computer and use it in GitHub Desktop.
Examples of multiple dispatch in JavaScript
widgetize.method(Error, Object, function(err) {
return err;
});
render.method(Error, Function, function(err, append) {
append($('<span/>').addClass('error').text(err));
});
// A special value to represent values we're waiting for
function Waiting() {}
widgetize.method(Waiting, Object, function(wait) {
return wait;
});
render.method(Waiting, Function, function(_, append) {
append($('<img/>').attr('src', 'ajax-loader.gif'));
});
function decodeValue(json) {
if (typeof(json) === 'object' && json) {
if (json.hasOwnProperty('!')) {
return decodeSpecial(json['!'], json);
}
return decodeObject(json);
}
return json;
}
var decodeObject = procedure('decodeObject');
decodeObject.method(Array, function(arr) {
var len = arr.length;
var vals = new Array(len);
for (var i = 0; i < len; i++) {
vals[i] = decodeValue(arr[i]);
}
return vals;
});
decodeObject.method(Object, function(obj) {
var res = {};
for (var k in obj) {
if (obj.hasOwnProperty(k)) res[k] = decodeValue(obj[k]);
}
return res;
});
var decodeSpecial = procedure('decodeSpecial');
decodeSpecial.method('undefined', Object, function() {
return undefined;
});
decodeSpecial.method('table', Object, function(_type, json) {
return new Table(json.data, json.columns);
});
var widgetize = procedure('widgetize');
var render = Widget.render;
// A superclass and API
function Presentation() {
Widget.call(this);
}
Presentation.prototype = inheritFrom(Widget);
// API
Presentation.widgetize = widgetize;
// Sometimes this is called with just one argument; so we don't
// have to specialise for each type twice, this transforms
// undefined (not a subtype of Object) into null.
widgetize.method(Object, undefined, function(val, _parent) {
return widgetize(val, null);
});
function primitive(val, parent) { return val; }
widgetize.method(String, Object, primitive);
widgetize.method(Boolean, Object, primitive);
widgetize.method(Number, Object, primitive);
widgetize.method(null, Object, primitive);
widgetize.method(undefined, Object, primitive);
widgetize.method(undefined, undefined, primitive);
// primitives are given as the value rather than a widget. Use this as a fallback.
function renderPrimitive(val, appender, type) {
appender($('<code/>').addClass(type || typeof(val)).text(String(val)));
}
render.method(Object, Function, renderPrimitive);
render.method(null, Function, function(val, app) {
return renderPrimitive('null', app, 'null');
});
render.method(String, Function, function(val, app) {
return renderPrimitive('"' + val + '"', app);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment