tl;dr
Ensure your arguments are of the proper type:
$('login').addEvent(
'click',
function (event) {
// type hinting/enforcement
TypeHinter.benchmark('file.js', 'function::anon');
TypeHinter.check(
[event, Event]
);
// function logic
event.stop();
// ...
}
);
Introduction
TypeHinter is a type hinting/argument enforcing script which helps in the debugging of both server and client side Javascript. It currently provides 5 simple and straightforward methods which allow you to, in alphabetical order:
benchmark
: benchmark/mark which methods/functions are receiving invalid parameter typescheck
: perform a check against the passed in function/method argumentsoff
: turn the checking off (useful for production environments)on
: turn the checking onstrict(on)
: mark whether or not error's should be thrown or logged
Background
In setting up one of my first GitHub repo's, I thought TypeHinter.class.js would be a good candidate since it's a pretty simple class/script, works on both client and server stacks, and is good at one specific thing.
Flow
Whenever a function or method is defined, I separate the logic out into two components:
- argument validation
- function/method logic
Before anything happens in the function/method, I simply check to make sure that the arguments are the exact object types I expect. If this fails, an error is either logged, or thrown.
Example
Before I go into the details of how the script works, I'll show an example:
$('login').addEvent(
'click',
function (event) {
// type hinting/enforcement
TypeHinter.benchmark('file.js', 'function::anon');
TypeHinter.check(
[event, Event]
);
// function logic
event.stop();
// ...
}
);
This is a pretty straight forward event handler. Before any of the function
logic gets executed, a call is made to TypeHinter.benchmark
, with the filename
and function name (if it exists) as an argument. If this isn't done, the
TypeHinter will throw an error. This is pretty important for debugging, so I
figured I'd make it mandatory.
After this, a call to the TypeHinter.check
method is made. It can receive an
unlimited number of arguments, with each argument an array of mixed objects. So
in this case, we have one argument being passed as:
[event, Event]
This contains the event object that was initially passed as the event-handler's
callback, as well as a reference to the Event class. As brushed-over initially,
the TypeHinter loops over the arguments passed in, and ensures that they are the
valid type. Therefore in this case, if the argument passed to the
event-handler's callback is a string, array, or not defined (aka. not passed to
the function at all), the TypeHinter will throw an error (or simply log it to
the console depending on whether you made a call to TypeHinter.strict(false))
.
Summary
It's a pretty simple little class. My motivation behind this was through my exposure to nodejs. Parameters are flying around way more often and casually on the server side than on the client side (imo), and this lead to a lot of debugging of parameter types of my part. I found this helpful, especially when dealing with external data-sets such as APIs and storage-systems.
More Examples
Passed in argument must be a String or Object
function(arg) {
// type hinting/enforcement
TypeHinter.benchmark('file.js', 'name');
TypeHinter.check(
[arg, String, Object]
);
// function logic
// ...
}
First argument only is checked against being a String or an instance of the
CustomClass
class
function(arg1, arg2) {
// type hinting/enforcement
TypeHinter.benchmark('file.js', 'name');
TypeHinter.check(
[arg1, String, CustomClass]
);
// function logic
// ...
}
First argument must be a String or Object; the second argument must be passed, but can be of any type (excluding undefined)
function(arg1, arg2) {
// type hinting/enforcement
TypeHinter.benchmark('file.js', 'name');
TypeHinter.check(
[arg1, String, Object],
[arg2]
);
// function logic
// ...
}
First argument must be a String or Object; the second argument can either be a String or undefined (aka. not passed)
function(arg1, arg2) {
// type hinting/enforcement
TypeHinter.benchmark('file.js', 'name');
TypeHinter.check(
[arg1, String, Object],
[arg2, String, undefined]
);
// function logic
// ...
}
Neither arguments have any restrictions (eg. won't be checked)
function(arg1, arg2) {
// type hinting/enforcement
TypeHinter.benchmark('file.js', 'name');
TypeHinter.check();
// function logic
// ...
}