Search code examples
javascriptobjecttypeof

How to check for an object in Javascript?


Real-world usage

typeof is very useful, but it's not as versatile as might be required. For example, typeof([]) , is 'object', as well as typeof(new Date()), typeof(/abc/), etc.

For greater specificity in checking types, a typeof wrapper for usage in production-level code would be as follows (provided obj 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!


Solution

  • 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]

    1. What 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'

    1. What 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.