Better way to get type of a Javascript variable?

JavascriptTypesTypeof

Javascript Problem Overview


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?

Javascript Solutions


Solution 1 - Javascript

Angus Croll recently wrote an interesting blog post about this -

http://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/

He goes through the pros and cons of the various methods then defines a new method 'toType' -

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

Solution 2 - Javascript

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(/./)

Solution 3 - Javascript

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

Solution 4 - Javascript

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

Solution 5 - Javascript

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'

Solution 6 - Javascript

one line function:

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

this give the same result as jQuery.type()

Solution 7 - Javascript

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

Solution 8 - Javascript

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.

Solution 9 - Javascript

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

Solution 10 - Javascript

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.

Solution 11 - Javascript

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'

Solution 12 - Javascript

I've made this function:

( You should name it more unique so it doesn't collide with some other global name. )

function type(theThing) {
    return Object.prototype.toString.call(theThing).match(/\s([\w]+)/)[1].toLowerCase()
}
type({})           //-> 'object'
type([])           //-> 'array'
type(function(){}) //-> 'function'
    
type(null)         //-> 'null'
type(undefined)    //-> 'undefined
type(true)         //-> 'boolean'
type('hello')      //-> 'string'
type(42)           //-> 'number'

type(Symbol())     //-> 'symbol'
type(/abc/)        //-> 'regexp'
type(new Set())    //-> 'set'
// etc ...

PS: F.NiX above made more robust version that also tell you the name of your custom objects made from Class or constructor function.

Solution 13 - Javascript

https://npmjs.com/package/advanced-type

I created a package for this purpose.

Solution 14 - Javascript

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")
{

}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAillynView Question on Stackoverflow
Solution 1 - Javascriptipr101View Answer on Stackoverflow
Solution 2 - JavascriptAlex TurpinView Answer on Stackoverflow
Solution 3 - JavascriptVixView Answer on Stackoverflow
Solution 4 - JavascriptNick HusherView Answer on Stackoverflow
Solution 5 - JavascriptgreymasterView Answer on Stackoverflow
Solution 6 - JavascriptYukuléléView Answer on Stackoverflow
Solution 7 - JavascriptAndy EView Answer on Stackoverflow
Solution 8 - JavascriptSpYk3HHView Answer on Stackoverflow
Solution 9 - JavascriptF.NiXView Answer on Stackoverflow
Solution 10 - JavascriptmpenView Answer on Stackoverflow
Solution 11 - JavascriptArsenowitchView Answer on Stackoverflow
Solution 12 - JavascriptJsonKodyView Answer on Stackoverflow
Solution 13 - JavascriptHuman FriendView Answer on Stackoverflow
Solution 14 - JavascriptMzkZeeshanView Answer on Stackoverflow