Reputation: 3902
I'm wondering if it's appropriate to use Object.prototype.toString() for general type checking with built-in types. I have a function that looks like this:
// Return the built-in type of an object.
var typeOf = (function() {
var reType = /\[object (\w+)\]/;
return function typeOf(obj) {
return reType.exec(Object.prototype.toString.call(obj))[1];
};
})();
Calls to the function return the following results:
console.log( typeOf(null) ); // => Null
console.log( typeOf(undefined) ); // => Undefined
console.log( typeOf([]) ); // => Array
console.log( typeOf(true) ); // => Boolean
console.log( typeOf(new Date()) ); // => Date
console.log( typeOf(new Error()) ); // => Error
console.log( typeOf(function(){}) ); // => Function
console.log( typeOf(1) ); // => Number
console.log( typeOf({}) ); // => Object
console.log( typeOf(/ /) ); // => RegExp
console.log( typeOf("") ); // => String
Is this acceptable other than the fact it might be slower than other forms of type checking?
One of the reasons I'm asking is because I'm wanting to encode and serialize an object's built-in type for a project I'm working on. I'm looking at passing the returned type to a function which returns a numeric code:
// Encode a built-in type as a number.
var encodeType = (function() {
var types = {
'Null': 0,
'Undefined': 1,
'Array': 2,
'Boolean': 3,
'Date': 4,
'Error': 5,
'Function': 6,
'Number': 7,
'Object': 8,
'RegExp': 9,
'String': 10,
'Arguments': 11,
'Math': 12,
'JSON': 13
};
return function encodeType(type) {
return types[type];
}
})();
So the output becomes:
console.log(encodeType( typeOf(null) )); // => 0
console.log(encodeType( typeOf(undefined) )); // => 1
console.log(encodeType( typeOf([]) )); // => 2
console.log(encodeType( typeOf(true) )); // => 3
console.log(encodeType( typeOf(new Date()) )); // => 4
console.log(encodeType( typeOf(new Error()) )); // => 5
console.log(encodeType( typeOf(function(){}) )); // => 6
console.log(encodeType( typeOf(1) )); // => 7
console.log(encodeType( typeOf({}) )); // => 8
console.log(encodeType( typeOf(/ /) )); // => 9
console.log(encodeType( typeOf("") )); // => 10
Are there any pitfalls with type checking this way? Thanks for any insights.
Upvotes: 4
Views: 239
Reputation: 2609
I don't understand all of the extra syntax. Wouldn't this do the exact same thing?
var typeOf = function(obj) {
var reType = /\[object (\w+)\]/;
return reType.exec(Object.prototype.toString.call(obj))[1];
};
Also, it might be better to use a switch for encodeType
Upvotes: 0
Reputation: 19987
Here is underscore.js' implementation:
// Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError.
_.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) {
_['is' + name] = function(obj) {
return toString.call(obj) === '[object ' + name + ']';
};
});
So yes, this method is good to go.
P.S. toString
is short for Object.prototype.toString
in the above code.
Upvotes: 3