The question it more about the design of the code and how it could be written better. The code itself works as it should.
A little about the code itself: the function checks the object passed as the first argument and either return a string with the type of object (array
, date
, xmlhttprequest
, etc.) or a Boolean when comparing an object with a string value.
The function can also iterate through an array of objects and returns a Boolean value, an array of Boolean results, or an object.
(function ( global ) {
"use strict";
Object.type = function type( testObject, testAgainst, returnType ) {
var result, getType = function ( object ) {
var result;
if ( object && object.nodeType !== undefined ) {
result = 'dom';
}
else if ( object === global ) {
result = 'global';
}
else {
result = ({}).toString.call( object ).match( /\s([a-zA-Z]+)/ )[1].toLowerCase();
}
return result;
};
if ( getType( testAgainst ) !== 'undefined' ) {
if ( getType( testAgainst ) === 'string' ) {
return getType( testObject ) === testAgainst;
}
else if ( getType( testAgainst ) === 'array' ) {
if ( getType( returnType ) === 'undefined' ) {
returnType = 'boolean';
}
result = {
'boolean': function () {
return testObject.every(function ( member, index ) {
return getType( member ) === testAgainst[index];
});
},
'array': function () {
return testObject.map(function ( member, index ) {
return getType( member ) === testAgainst[index];
});
},
'object': function () {
var result = {};
testObject.forEach(function ( member, index ) {
result[ getType( member ) ] = getType( member) === testAgainst[index];
});
return result;
}
};
return result[ returnType ]();
}
}
return getType( testObject );
};
}( this ));
Usage examples:
(function () {
var objects = [null, 0, undefined, new Date(), new XMLHttpRequest(), function () {}, {}, [], 'string'],
matches = ['null', 'number', 'undefined', 'date', 'xmlhttprequest', 'function', 'object', 'array', 'string'],
misses = ['array', 'number', 'string', 'date', 'xmlhttprequest', 'function', 'object', 'number', 'string'];
console.dir({
"objects array: ": objects,
"matches array: ": matches,
"misses array: ": misses,
"Object.type( {} )": Object.type( {} ), //returns 'object'
"Object.type( 2013, 'number' )": Object.type( 2013, 'number' ), //returns true
"Object.type( objects, matches )": Object.type( objects, matches), //returns true
"Object.type( objects, misses )": Object.type( objects, misses ), //returns false
"Object.type( objects, matches, 'object' )": Object.type( objects, matches, 'object' ),
"Object.type( objects, matches, 'array' )": Object.type( objects, matches, 'array' ), //returns Array[9] (true, true, true, true, true, true, true, true, true)
"Object.type( objects, misses, 'object' )": Object.type( objects, misses, 'object' ),
"Object.type( objects, misses, 'array' )": Object.type( objects, misses, 'array' ) //returns Array[9] (false, true, false, true, true, true, true, false, true)
});
}());
The problem with the design that mainly bugs me is that the majority of the code is inside nested if
statements.
What design changes I could make to this code to make it ready for production?
Edit:
I've created a gist where I updated the above code based on comments (https://gist.github.com/silverstrike/5108601)