Skip to content

Instantly share code, notes, and snippets.

@jabney
Last active August 29, 2015 14:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jabney/7c5970feb5ce72b05d40 to your computer and use it in GitHub Desktop.
Save jabney/7c5970feb5ce72b05d40 to your computer and use it in GitHub Desktop.
An experiment with "forward type checking" in JavaScript. Execute a method based upon an object's type.
// declare.js MIT License © 2014 James Abney http://github.com/jabney
// An experiment with "forward type checking". Register types
// using 'declare' along with corresponding methods. The methods
// get called depending upon the type of the passed object.
//
// // Create a new declare object.
// var logByType = fwdType.declare();
//
// // Register types and methods.
//
// logByType('Array', function(ary) {
// ary.forEach(function(item) {
// console.log('from array:', item);
// });
// });
//
// logByType('String', function(str) {
// str.split('').forEach(function(item) {
// console.log('from string:', item);
// });
// });
//
// logByType('Default', function(unknown) {
// console.log('default:', unknown);
// });
//
// // Execute by type.
// logByType.exec([1, 2, 3]);
// logByType.exec('abc');
// logByType.exec({1:'a', 2:'b', 3:'c'})
//
(function(ft) {
'use strict';
var
// Helpers
toString = Object.prototype.toString,
// Return the type of built-in objects via toString.
typeOf = (function() {
var reType = /\[object (\w+)\]/;
return function(obj) {
return reType.exec(toString.call(obj))[1];
};
})();
// Create a new declaration object.
ft.declare = function() {
var methods = Object.create(null),
contexts = Object.create(null);
// Declare a type and the method that should handle it.
return function declare(type, method, context) {
methods[type] = method;
context && (contexts[type] = context);
// Execute against an object, calling a registered type.
declare.exec = function exec(obj, context) {
var type = typeOf(obj),
method = methods[type],
def = methods['Default'];
// If the method doesn't exist, call default if specified.
if (method)
method.call(context || contexts[type], obj);
else if (def)
def.call(context || contexts['Default'], obj);
return exec;
};
return declare;
};
};
})(window.fwdType = window.fwdType || Object.create(null));
// A few basic tests.
(function(ft) {
// A function chaining syntax allowed by the pattern.
// These are just successive function calls.
var logTypes = ft.declare()
('Array', function(ary) {
console.log('this is an array:', ary);
})
('Function', function(fn) {
console.log('this is a function:', fn);
})
('String', function(str) {
console.log('this is a string:', str);
})
('Default', function(obj) {
console.log('this is the default:', obj)
});
logTypes.exec([1, 2, 3])
(function(){})
('string')
(1);
})(window.fwdType);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment