Last active
August 29, 2015 14:10
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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