/** * jQuery-Plugin to make type safe functions. * * see http://united-coders.com/matthias-reuter/handling-the-unexpected-type-safe-functions-in-javascript * * @author Matthias Reuter */ (function () { var types = { /** * Checks whether the argument is an integer number. * @param {Object} n */ "int" : function (n) { return n === parseInt(n, 10); }, /** * Checks whether the argument is a float number. * @param {Object} n */ "float" : function (n) { return typeof n === "number" && !isNaN(n); }, /** * Checks whether the argument is a string. * @param {Object} n */ "string" : function (n) { return typeof n === "string"; }, /** * Checks whether the argument is a boolean. * @param {Object} n */ "boolean" : function (n) { return typeof n === "boolean"; }, /** * Checks whether the argument is a character. * @param {Object} n */ "char" : function (n) { return typeof n === "string" && n.length === 1; }, /** * Checks whether the argument is an object and not null. * @param {Object} n */ "object" : function (n) { return n !== null && Object.prototype.toString.call(n) === "[object Object]"; }, /** * Checks whether the argument is an object and not null. * @param {Object} n */ "array" : function (n) { return Object.prototype.toString.call(n) === "[object Array]"; } }; // make double an alias of float types["double"] = types["float"]; /** * Checks whether the first argument is an array and every element is * of type denoted by second argument. * @param {Array} arr * @param {string} type */ var checkArray = function (arr, type) { if (!types["array"](arr)) { return false; } for (var i = 0, l = arr.length; i < l; i++) { if (types[type](arr[i])) { return false; } } return true; }; /** * Creates a wrapper that checks for valid arguments before calling a * function. * @param {function} f The function to make type safe * @param {Array} paramlist The list of expected arguments */ var makeTypeSafe = function (f, paramlist) { var p = paramlist ? paramlist.length : 0; var currentType; // Check arguments of creator function if (typeof f !== "function") { throw "Argument is not a function"; } // If no (or empty) paramlist is given, just return f if (!p) { return f; } // Check paramlist for unknown types for (var i = 0; i < p; i++) { // remove [] at end of type to easily allow arrays of one type currentType = paramlist[i].replace(/\[\]$/, ""); if (!(paramlist[i] in types)) { throw "Unknown type " + paramlist[i]; } } // create and return wrapper function return function () { var currentType, valid, i, l; // Check number of arguments if (arguments.length !== p) { throw "Unexpected number of arguments. Expected " + p + ", got " + arguments.length + "."; } // Check arguments for (i = 0, l = Math.min(arguments.length, p); i < l; i++) { currentType = paramlist[i]; valid = true; // if type end with [] check if argument is an array of // according type if (currentType.indexOf("[]") === currentType.length - 2) { valid = checkArray(arguments[i], currentType.substring(0, currentType.length - 2)); } else { valid = types[currentType](arguments[i]); } if (!valid) { throw "Invalid argument at " + i + ". Argument must be of type " + currentType + "."; } } // If everything is ok so far, call f return f.apply(this, arguments); }; }; jQuery.makeTypeSafe = makeTypeSafe; jQuery.makeTypeSafe.types = types; })();