[javascript] Better way to get type of a Javascript variable?

Is there a better way to get the type of a variable in JS than typeof? It works fine when you do:

> typeof 1
"number"
> typeof "hello"
"string"

But it's useless when you try:

> typeof [1,2]
"object"
>r = new RegExp(/./)
/./
> typeof r
"function"

I know of instanceof, but this requires you to know the type beforehand.

> [1,2] instanceof Array
true
> r instanceof RegExp
true

Is there a better way?

This question is related to javascript types typeof

The answer is


This version is a more complete one:

const typeOf = obj => {
  let type = ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1]
  if (type === 'Object') {
    const results = (/^(function|class)\s+(\w+)/).exec(obj.constructor.toString())
    type = (results && results.length > 2) ? results[2] : ''
  }
  return type.toLowerCase()
}

Now not only you can have these results: (as they've been answered here)

undefined or empty -> undefined
null -> null
NaN -> number
5 -> number
{} -> object
[] -> array
'' -> string
function () {} -> function
/a/ -> regexp
new Date() -> date
new Error -> error
Promise.resolve() -> promise
function *() {} -> generatorfunction
new WeakMap() -> weakmap
new Map() -> map

But also you can get the type of every instance or object you construct from classes or functions: (which is not valid between other answers, all of them return object)

class C {
  constructor() {
    this.a = 1
  }
}

function F() {
  this.b = 'Foad'
}

typeOf(new C()) // -> c
typeOf(new F()) // -> f

A reasonably good type capture function is the one used by YUI3:

var TYPES = {
    'undefined'        : 'undefined',
    'number'           : 'number',
    'boolean'          : 'boolean',
    'string'           : 'string',
    '[object Function]': 'function',
    '[object RegExp]'  : 'regexp',
    '[object Array]'   : 'array',
    '[object Date]'    : 'date',
    '[object Error]'   : 'error'
},
TOSTRING = Object.prototype.toString;

function type(o) {
    return TYPES[typeof o] || TYPES[TOSTRING.call(o)] || (o ? 'object' : 'null');
};

This captures many of the primitives provided by javascript, but you can always add more by modifying the TYPES object. Note that typeof HTMLElementCollection in Safari will report function, but type(HTMLElementCollection) will return object


typeof condition is used to check variable type, if you are check variable type in if-else condition e.g.

if(typeof Varaible_Name "undefined")
{

}

You can try using constructor.name.

[].constructor.name
new RegExp().constructor.name

As with everything JavaScript, someone will eventually invariably point that this is somehow evil, so here is a link to an answer that covers this pretty well.

An alternative is to use Object.prototype.toString.call

Object.prototype.toString.call([])
Object.prototype.toString.call(/./)

You can apply Object.prototype.toString to any object:

var toString = Object.prototype.toString;

console.log(toString.call([]));
//-> [object Array]

console.log(toString.call(/reg/g));
//-> [object RegExp]

console.log(toString.call({}));
//-> [object Object]

This works well in all browsers, with the exception of IE - when calling this on a variable obtained from another window it will just spit out [object Object].


function getType(obj) {
    if(obj && obj.constructor && obj.constructor.name) {
        return obj.constructor.name;
    }
    return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
}

In my preliminary tests, this is working pretty well. The first case will print the name of any object created with "new", and the 2nd case should catch everything else.

I'm using (8, -1) because I'm assuming that the result is always going to start with [object and end with ] but I'm not certain that's true in every scenario.


My 2ยข! Really, part of the reason I'm throwing this up here, despite the long list of answers, is to provide a little more all in one type solution and get some feed back in the future on how to expand it to include more real types.

With the following solution, as aforementioned, I combined a couple of solutions found here, as well as incorporate a fix for returning a value of jQuery on jQuery defined object if available. I also append the method to the native Object prototype. I know that is often taboo, as it could interfere with other such extensions, but I leave that to user beware. If you don't like this way of doing it, simply copy the base function anywhere you like and replace all variables of this with an argument parameter to pass in (such as arguments[0]).

;(function() {  //  Object.realType
    function realType(toLower) {
        var r = typeof this;
        try {
            if (window.hasOwnProperty('jQuery') && this.constructor && this.constructor == jQuery) r = 'jQuery';
            else r = this.constructor && this.constructor.name ? this.constructor.name : Object.prototype.toString.call(this).slice(8, -1);
        }
        catch(e) { if (this['toString']) r = this.toString().slice(8, -1); }
        return !toLower ? r : r.toLowerCase();
    }
    Object['defineProperty'] && !Object.prototype.hasOwnProperty('realType')
        ? Object.defineProperty(Object.prototype, 'realType', { value: realType }) : Object.prototype['realType'] = realType;
})();

Then simply use with ease, like so:

obj.realType()  //  would return 'Object'
obj.realType(true)  //  would return 'object'

Note: There is 1 argument passable. If is bool of true, then the return will always be in lowercase.

More Examples:

true.realType();                            //  "Boolean"
var a = 4; a.realType();                    //  "Number"
$('div:first').realType();                   // "jQuery"
document.createElement('div').realType()    //  "HTMLDivElement"

If you have anything to add that maybe helpful, such as defining when an object was created with another library (Moo, Proto, Yui, Dojo, etc...) please feel free to comment or edit this and keep it going to be more accurate and precise. OR roll on over to the GitHub I made for it and let me know. You'll also find a quick link to a cdn min file there.


I guess the most universal solution here - is to check for undefined and null first, then just call constructor.name.toLowerCase().

const getType = v =>
  v === undefined
    ? 'undefined'
    : v === null
      ? 'null'
      : v.constructor.name.toLowerCase();




console.log(getType(undefined)); // 'undefined'
console.log(getType(null)); // 'null'
console.log(getType('')); // 'string'
console.log(getType([])); // 'array'
console.log(getType({})); // 'object'
console.log(getType(new Set())); // `set'
console.log(getType(Promise.resolve())); // `promise'
console.log(getType(new Map())); // `map'

Also we can change a little example from ipr101

Object.prototype.toType = function() {
  return ({}).toString.call(this).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}

and call as

"aaa".toType(); // 'string'

You may find the following function useful:

function typeOf(obj) {
  return {}.toString.call(obj).split(' ')[1].slice(0, -1).toLowerCase();
}

Or in ES7 (comment if further improvements)

const { toString } = Object.prototype;

function typeOf(obj) {
  const stringified = obj::toString();
  const type = stringified.split(' ')[1].slice(0, -1);
      
  return type.toLowerCase();
}

Results:

typeOf(); //undefined
typeOf(null); //null
typeOf(NaN); //number
typeOf(5); //number
typeOf({}); //object
typeOf([]); //array
typeOf(''); //string
typeOf(function () {}); //function
typeOf(/a/) //regexp
typeOf(new Date()) //date
typeOf(new Error) //error
typeOf(Promise.resolve()) //promise
typeOf(function *() {}) //generatorfunction
typeOf(new WeakMap()) //weakmap
typeOf(new Map()) //map
typeOf(async function() {}) //asyncfunction

Thanks @johnrees for notifying me of: error, promise, generatorfunction


one line function:

function type(obj) {
    return Object.prototype.toString.call(obj).replace(/^\[object (.+)\]$/,"$1").toLowerCase()
}

this give the same result as jQuery.type()


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to types

Cannot invoke an expression whose type lacks a call signature How to declare a Fixed length Array in TypeScript Typescript input onchange event.target.value Error: Cannot invoke an expression whose type lacks a call signature Class constructor type in typescript? What is dtype('O'), in pandas? YAML equivalent of array of objects in JSON Converting std::__cxx11::string to std::string Append a tuple to a list - what's the difference between two ways? How to check if type is Boolean

Examples related to typeof

Get class name of object as string in Swift Why does typeof array with objects return "object" and not "array"? Get type of all variables How to cast Object to its actual type? typeof operator in C When and where to use GetType() or typeof()? How do I get the type of a variable? How to efficiently check if variable is Array or Object (in NodeJS & V8)? Better way to get type of a Javascript variable? C# switch on type