patternjavascriptMinor
Generalized is() type-checking function for JavaScript
Viewed 0 times
generalizedjavascriptcheckingfunctiontypefor
Problem
In a complex library I've been working on, I got pretty tired of all of the individual type functions and operators to determine whether I was working with an object or piece of data of a given type. This was especially true when I was checking for inherited prototypes between classes. In an effort to alleviate, I made this generalized is() function.
Syntax
Usage
I use this function whenever the type of a value is imperative. One common example is when I need different behaviors depending on the type. As an example:
Reasons for this function
The goal is to reduce the amount of
( function( root ) {
var is = function( v, t ) {
if ( typeof v !== 'undefined' ) {
if ( typeof t === 'string' )
return typeof v === t;
else if ( typeof t === 'function' ) {
if ( typeof v === 'object' )
return v instanceof t;
else if ( typeof v === 'function' )
return t.prototype.isPrototypeOf( v.prototype );
else return false;
}
}
return false;
};
root['is'] = is;
}( this ) );Syntax
is(variable, type)where type is any return fromtypeof
- returns true if
variabletypeof ===type
is(variable, class)where variable is an object and class is a constructor
- returns true if
variableis an instanceofclass
is(class1, class2)where class is a constructor and class is a constructor
- returns true if
class1's prototype is a descendant ofclass2's prototype.
Usage
I use this function whenever the type of a value is imperative. One common example is when I need different behaviors depending on the type. As an example:
// typeof myVar === 'number'
if(is(myVar,'number')) {
doSomething();
}
// myVar instanceof Array
elseif (is(myVar,Array)) {
doSomethingWithArray();
}
// typeof myVar === 'object'
elseif (is(myVar,'object')) {
doSomethingWithObject();
}Reasons for this function
The goal is to reduce the amount of
typeof, instanceof and isPrototypeOf statements, as well as the need for individualized type checking methods. This certainly seems to accomplish much oSolution
Code Review
Coding Style
You coding style is quite uncommon. However, it is fine if it is consistent across
your projects.
My personal preference is to use constant ahead of comparison so it looks a
little bit less confusing:
Anyway, in this particular case it is sematically better to use
emphasises that the variable is immutable within the statement:
Some style guides also recommend to remove redundant
will decrease indentation and simplify the code statements.
It is better to use a little bit descriptive variable names. For example,
You can elliminate the variable
root's property. Or there is a special preference to keep the variable
Logic
It is doubtful whether this function should return
will fail.
If the argument value is not supported, it may be better to throw an exception
instead of returning plausible value. For example,
false, but
I understand that it contradicts a little with an original purpose of the function
but it looks like this usage of the function may be quite handy.
Please also be aware of multi-instance environment. If Array object created
within one vm instance (or iframe),
more examples here: http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
Revised Code
BTW, its minified version is 8 bytes shorter (with closure-compiler)
Coding Style
You coding style is quite uncommon. However, it is fine if it is consistent across
your projects.
My personal preference is to use constant ahead of comparison so it looks a
little bit less confusing:
if ('function' === typeof v)Anyway, in this particular case it is sematically better to use
switch so itemphasises that the variable is immutable within the statement:
switch (typeof t) {
case 'string':
return t === typeof v;
case 'function':
...
}Some style guides also recommend to remove redundant
else after return. Thiswill decrease indentation and simplify the code statements.
It is better to use a little bit descriptive variable names. For example,
type instead of t and value instead of v.You can elliminate the variable
is by assigning the function directly toroot's property. Or there is a special preference to keep the variable
is?Logic
It is doubtful whether this function should return
false foris(undefined, 'undefined'). It looks like it is a completely valid check thatwill fail.
If the argument value is not supported, it may be better to throw an exception
instead of returning plausible value. For example,
is(null, null) will returnfalse, but
null is just not supported value of the parameter t.I understand that it contradicts a little with an original purpose of the function
but it looks like this usage of the function may be quite handy.
Please also be aware of multi-instance environment. If Array object created
within one vm instance (or iframe),
instanceof Array will fail. You can findmore examples here: http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
Revised Code
(function (root) {
root.is = function (value, type) {
if ('undefined' !== typeof value) {
switch (typeof type) {
case 'string':
return type === typeof value;
case 'function':
switch (typeof value) {
case 'object':
return value instanceof type;
case 'function':
return type.prototype.isPrototypeOf(value.prototype);
}
}
}
return false;
};
}(this));BTW, its minified version is 8 bytes shorter (with closure-compiler)
Code Snippets
if ('function' === typeof v)switch (typeof t) {
case 'string':
return t === typeof v;
case 'function':
...
}(function (root) {
root.is = function (value, type) {
if ('undefined' !== typeof value) {
switch (typeof type) {
case 'string':
return type === typeof value;
case 'function':
switch (typeof value) {
case 'object':
return value instanceof type;
case 'function':
return type.prototype.isPrototypeOf(value.prototype);
}
}
}
return false;
};
}(this));Context
StackExchange Code Review Q#33956, answer score: 4
Revisions (0)
No revisions yet.