Real-world usage
typeof is very useful, but it's not as versatile as might be required. For example,
typeof([])
, is'object'
, as well astypeof(new Date())
,typeof(/abc/)
, etc.For greater specificity in checking types, a
typeof
wrapper for usage in production-level code would be as follows (providedobj
exists):
function type(obj, showFullClass) {
// get toPrototypeString() of obj (handles all types)
if (showFullClass && typeof obj === "object") {
return Object.prototype.toString.call(obj);
}
if (obj == null) { return (obj + '').toLowerCase(); } // implicit toString() conversion
var deepType = Object.prototype.toString.call(obj).slice(8,-1).toLowerCase();
if (deepType === 'generatorfunction') { return 'function' }
// Prevent overspecificity (for example, [object HTMLDivElement], etc).
// Account for functionish Regexp (Android <=2.3), functionish <object> element (Chrome <=57, Firefox <=52), etc.
// String.prototype.match is universally supported.
return deepType.match(/^(array|bigint|date|error|function|generator|regexp|symbol)$/) ? deepType :
(typeof obj === 'object' || typeof obj === 'function') ? 'object' : typeof obj;
}
I have the above code snippet - referenced from the MDN webdocs - to be most useful in answering the stated question.URL:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof . I must admit though that getting to fully understand the code is proving difficult - for instance, what is the 'showFullClass' argument in the function declaration and what do the following lines do? var deepType = Object.prototype.toString.call(obj).slice(8,-1).toLowerCase();
and
return deepType.match(/^(array|bigint|date|error|function|generator|regexp|symbol)$/) ? deepType :(typeof obj === 'object' || typeof obj === 'function') ? 'object' : typeof obj;
Any help or assistance in code comprehension would be much appreciated!
Whenever we call toString
on an object it returns "[object type]"
, where type
is the object type. So the goal of the type(obj, showFullClass)
is to extract the type
from 'toString' output string.
1.What is the 'showFullClass' argument in the function declaration?
showFullClass is a boolean type. So if pass true in it , It will just return the output of toString
without any processing.
E.g.
type(new Date(),true)
will return [object Date]
var deepType = Object.prototype.toString.call(obj).slice(8,-1).toLowerCase();
do?It extracts the type
substring of "[object type]"
string and then convert it into lowercase. Which starts at 8th index of the string till the second last index of string. -1 means string extraction should end just before the last index(-1) of string.
E.g. If obj
is date object deepType
value will be 'date'
return deepType.match(/^(array|bigint|date|error|function|generator|regexp|symbol)$/) ? deepType :(typeof obj === 'object' || typeof obj === 'function') ? 'object' : typeof obj;
do?It checks if deepType
matches to either "array" or "bigint" or "date" or "error" or "function" or "generator" or "regexp" or "symbol" then it returns deepType
.
Otherwise if typeof obj
is 'object'
or 'function'
return 'object'
.
Otherwise for primitive types like string,number,etc return its type.