185

In Java, you can use instanceOf or getClass() on a variable to find out its type.

How do I find out a variable's type in JavaScript which isn't strongly-typed?

For example, how do I know if the bar is a Boolean or a Number, or a String?

function foo(bar) {
    // what do I do here?
}
Tom Tucker
  • 11,676
  • 22
  • 89
  • 130

12 Answers12

298

Use typeof:

> typeof "foo"
"string"
> typeof true
"boolean"
> typeof 42
"number"

So you can do:

if(typeof bar === 'number') {
   //whatever
}

Be careful though if you define these primitives with their object wrappers (which you should never do, use literals where ever possible):

> typeof new Boolean(false)
"object"
> typeof new String("foo")
"object"
> typeof new Number(42)
"object"

The type of an array is still object. Here you really need the instanceof operator.

Update:

Another interesting way is to examine the output of Object.prototype.toString:

> Object.prototype.toString.call([1,2,3])
"[object Array]"
> Object.prototype.toString.call("foo bar")
"[object String]"
> Object.prototype.toString.call(45)
"[object Number]"
> Object.prototype.toString.call(false)
"[object Boolean]"
> Object.prototype.toString.call(new String("foo bar"))
"[object String]"
> Object.prototype.toString.call(null)
"[object Null]"
> Object.prototype.toString.call(/123/)
"[object RegExp]"
> Object.prototype.toString.call(undefined)
"[object Undefined]"

With that you would not have to distinguish between primitive values and objects.

wzhscript
  • 3
  • 2
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • What would be the down side of using __proto__.constructor.name a siple function would be:function getVariableType(object){ return(object.__proto__.constructor.name); } – Stu Mar 04 '18 at 15:23
  • update to the function definition i listed above:function getVariableType(object){ return(object === undefined ? "Undefined" : object.__proto__.constructor.name); – Stu Mar 04 '18 at 16:06
  • The question asks how to find the type of a *variable*. Your answer shows how to find the type of a *value*. Those are completely different things. – Jörg W Mittag Aug 18 '20 at 12:22
32

typeof is only good for returning the "primitive" types such as number, boolean, object, string and symbols. You can also use instanceof to test if an object is of a specific type.

function MyObj(prop) {
  this.prop = prop;
}

var obj = new MyObj(10);

console.log(obj instanceof MyObj && obj instanceof Object); // outputs true
Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217
  • The question asks how to find the type of a *variable*. Your answer shows how to find the type of a *value*. Those are completely different things. – Jörg W Mittag Aug 18 '20 at 12:23
  • 1
    @JörgWMittag Care to explain what you mean? Instead of commenting on the problems with existing answers (that you copy pasted throughout), it'd be nicer if you just posted your own answer to explain the difference – Ruan Mendes Aug 18 '20 at 12:54
  • There already is a correct answer: https://stackoverflow.com/a/20369089/2988 no need to add my own, and the answer is trivial: variables in JavaScript *do not have types*, so it is impossible to get the type of a variable. – Jörg W Mittag Aug 18 '20 at 12:57
  • 2
    @JörgWMittag You're splitting hairs; we know variablse have dynamic types in JavaScript and the OP was clearly trying to figure out the type of a value contained by a variable – Ruan Mendes Aug 18 '20 at 12:58
28

Using type:

// Numbers
typeof 37                === 'number';
typeof 3.14              === 'number';
typeof Math.LN2          === 'number';
typeof Infinity          === 'number';
typeof NaN               === 'number'; // Despite being "Not-A-Number"
typeof Number(1)         === 'number'; // but never use this form!

// Strings
typeof ""                === 'string';
typeof "bla"             === 'string';
typeof (typeof 1)        === 'string'; // typeof always return a string
typeof String("abc")     === 'string'; // but never use this form!

// Booleans
typeof true              === 'boolean';
typeof false             === 'boolean';
typeof Boolean(true)     === 'boolean'; // but never use this form!

// Undefined
typeof undefined         === 'undefined';
typeof blabla            === 'undefined'; // an undefined variable

// Objects
typeof {a:1}             === 'object';
typeof [1, 2, 4]         === 'object'; // use Array.isArray or Object.prototype.toString.call to differentiate regular objects from arrays
typeof new Date()        === 'object';
typeof new Boolean(true) === 'object'; // this is confusing. Don't use!
typeof new Number(1)     === 'object'; // this is confusing. Don't use!
typeof new String("abc") === 'object';  // this is confusing. Don't use!

// Functions
typeof function(){}      === 'function';
typeof Math.sin          === 'function';
Jojodmo
  • 23,357
  • 13
  • 65
  • 107
krishna singh
  • 1,023
  • 1
  • 11
  • 15
  • There are no problems with using `Number(1), Boolean(true)...` The only problems are when you use `new` and a boxed object is created, using them as functions can be actually be useful converting from other types. `Boolean(0) === false, Number(true) === 1` – Ruan Mendes Jul 16 '18 at 15:08
  • what about `null` ? `typeof null` is 'object' – some_groceries Oct 03 '19 at 12:36
  • The question asks how to find the type of a *variable*. Your answer shows how to find the type of a *value*. Those are completely different things. – Jörg W Mittag Aug 18 '20 at 12:23
26

In Javascript you can do that by using the typeof function

console.log(typeof bar);
Barlas Apaydin
  • 7,233
  • 11
  • 55
  • 86
wajiw
  • 12,239
  • 17
  • 54
  • 73
  • 3
    Like I mentioned in my answer, typof will only return number, boolean, object, string. Not useful for determining any other types, like Array, RegExp or custom types. – Ruan Mendes Jan 05 '11 at 21:11
  • 1
    The question asks how to find the type of a *variable*. Your answer shows how to find the type of a *value*. Those are completely different things. Also, `typeof` is an operator not a function. – Jörg W Mittag Aug 18 '20 at 12:23
10

To be a little more ECMAScript-5.1-precise than the other answers (some might say pedantic):

In JavaScript, variables (and properties) don't have types: values do. Further, there are only 6 types of values: Undefined, Null, Boolean, String, Number, and Object. (Technically, there are also 7 "specification types", but you can't store values of those types as properties of objects or values of variables--they are only used within the spec itself, to define how the language works. The values you can explicitly manipulate are of only the 6 types I listed.)

The spec uses the notation "Type(x)" when it wants to talk about "the type of x". This is only a notation used within the spec: it is not a feature of the language.

As other answers make clear, in practice you may well want to know more than the type of a value--particularly when the type is Object. Regardless, and for completeness, here is a simple JavaScript implementation of Type(x) as it is used in the spec:

function Type(x) { 
    if (x === null) {
        return 'Null';
    }

    switch (typeof x) {
    case 'undefined': return 'Undefined';
    case 'boolean'  : return 'Boolean';
    case 'number'   : return 'Number';
    case 'string'   : return 'String';
    default         : return 'Object';
    }
}
Wes
  • 126
  • 1
  • 4
7

I find it frustrating that typeof is so limited. Here’s an improved version:

var realtypeof = function (obj) {
    switch (typeof(obj)) {
        // object prototypes
        case 'object':
            if (obj instanceof Array)
                return '[object Array]';
            if (obj instanceof Date)
                return '[object Date]';
            if (obj instanceof RegExp)
                return '[object regexp]';
            if (obj instanceof String)
                return '[object String]';
            if (obj instanceof Number)
                return '[object Number]';

            return 'object';
        // object literals
        default:
            return typeof(obj);
    }   
};

sample test:

realtypeof( '' ) // "string"
realtypeof( new String('') ) // "[object String]"
Object.prototype.toString.call("foo bar") //"[object String]" 
Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217
Tom Söderlund
  • 4,743
  • 4
  • 45
  • 67
  • The question asks how to find the type of a *variable*. Your answer shows how to find the type of a *value*. Those are completely different things. – Jörg W Mittag Aug 18 '20 at 12:24
6

For builtin JS types you can use:

function getTypeName(val) {
    return {}.toString.call(val).slice(8, -1);
}

Here we use 'toString' method from 'Object' class which works different than the same method of another types.

Examples:

// Primitives
getTypeName(42);        // "Number"
getTypeName("hi");      // "String"
getTypeName(true);      // "Boolean"
getTypeName(Symbol('s'))// "Symbol"
getTypeName(null);      // "Null"
getTypeName(undefined); // "Undefined"

// Non-primitives
getTypeName({});            // "Object"
getTypeName([]);            // "Array"
getTypeName(new Date);      // "Date"
getTypeName(function() {}); // "Function"
getTypeName(/a/);           // "RegExp"
getTypeName(new Error);     // "Error"

If you need a class name you can use:

instance.constructor.name

Examples:

({}).constructor.name       // "Object"
[].constructor.name         // "Array"
(new Date).constructor.name // "Date"

function MyClass() {}
let my = new MyClass();
my.constructor.name         // "MyClass"

But this feature was added in ES2015.

WebBrother
  • 1,447
  • 20
  • 31
  • The question asks how to find the type of a *variable*. Your answer shows how to find the type of a *value*. Those are completely different things. – Jörg W Mittag Aug 18 '20 at 12:24
  • @JörgWMittag you can pass a variable to `getTypeName` function, and it will work correctly. Example: `let a = 42; getTypeName(a) // "Number"` – WebBrother Feb 04 '21 at 08:37
  • But this will *still* give you the type of the *value that is assigned to the variable*. It will not give you the type of the *variable*. The question, however, explicitly asks about finding the type of the variable, not the value. – Jörg W Mittag Feb 04 '21 at 09:31
  • What is the difference between types of value and variable that has that value? When you assign value to the variable they will always have the same type. In JS there is no way to define a variable with some type without assigning the value. – WebBrother Feb 04 '21 at 09:39
  • 1
    @JörgWMittag I'm also confused by your comment here and on other answers. What should the type of *the variable* be if not based on the value assigned to it? Note that OP draws a parallel with Java and `getClass()` and `instanceof` work on the *value* regardless of what the type it was declared with. For example for `Object foo = "hello";` calling `foo.getClass()` will produce `Class`. Calling `foo instanceof String` will similarly produce `true`. – VLAZ Mar 18 '21 at 14:14
  • I guess Jord doesn't know that JS variables don't have their own types, because JS is not a typed language. – WebBrother Dec 23 '21 at 10:03
2

In JavaScript everything is an object

console.log(type of({}))  //Object
console.log(type of([]))  //Object

To get Real type , use this

console.log(Object.prototype.toString.call({}))   //[object Object]
console.log(Object.prototype.toString.call([]))   //[object Array]

Hope this helps

  • The question asks how to find the type of a *variable*. Your answer shows how to find the type of a *value*. Those are completely different things. – Jörg W Mittag Aug 18 '20 at 12:24
2

Many people suggest typeOf but forget JS qwirks. Here is the one liner utility function you can use

const trueTypeOf = (obj) => Object.prototype.toString.call(obj).slice(8, -1).toLowerCase()

Output:

trueTypeOf([]); // array
trueTypeOf({}); // object
trueTypeOf(''); // string
trueTypeOf(new Date()); // date
trueTypeOf(1); // number
trueTypeOf(function () {}); // function.
trueTypeOf(/test/i); // regexp
trueTypeOf(true); // boolean
trueTypeOf(null); // null
trueTypeOf(); // undefined
minigeek
  • 2,766
  • 1
  • 25
  • 35
1

Hopefully a complete one… What's missing?

Repo + tests: GitHub:ppo/…/true-typeof

const trueTypeOf = (value) => {
  const type = typeof value;

  if (type === 'number') {
    if (Number.isInteger(value)) return 'integer';
    return 'float';
  }
  if (type === 'function') {
    if (/^\s*class\s+/.test(value.toString())) return 'class';
    return 'function';
  }
  if (type !== 'object') return type;
  if (value === null) return 'null';
  if (Array.isArray(value)) return 'array';
  if (value.constructor.name === 'Object') return 'dictionary';
  return Object.prototype.toString.call(value).slice(8, -1).toLowerCase();
};
  // Base types OK via `typeof`
  undefined             → 'undefined'
  true                  → 'boolean'
  false                 → 'boolean'
  ''                    → 'string'
  'abc'                 → 'string'
  `${foo}-bar`          → 'string'

  // Numbers
  1                     → 'integer'
  1.0                   → 'integer'
  1.1                   → 'float'

  // Functions & classes
  function() {}         → 'function'
  myFunction            → 'function'
  class A {}            → 'class'
  MyClass               → 'class'
  new MyClass()         → 'object'
  MyClass.staticMethod  → 'function'

  // Base types not OK via `typeof`
  null                  → 'null'
  []                    → 'array'
  {}                    → 'dictionary'

  // Any class implementing `Object.prototype.toString()`
  new Set()             → 'set'
  new Date()            → 'date'
  /test/i               → 'regexp'
  new RegExp('test')    → 'regexp'
  new Error()           → 'error'
  new TypeError()       → 'error'
Pascal Polleunus
  • 2,411
  • 2
  • 28
  • 30
0

Here is the Complete solution.

You can also use it as a Helper class in your Projects.

"use strict";
/**
 * @description Util file
 * @author Tarandeep Singh
 * @created 2016-08-09
 */

window.Sys = {};

Sys = {
  isEmptyObject: function(val) {
    return this.isObject(val) && Object.keys(val).length;
  },
  /** This Returns Object Type */
  getType: function(val) {
    return Object.prototype.toString.call(val);
  },
  /** This Checks and Return if Object is Defined */
  isDefined: function(val) {
    return val !== void 0 || typeof val !== 'undefined';
  },
  /** Run a Map on an Array **/
  map: function(arr, fn) {
    var res = [],
      i = 0;
    for (; i < arr.length; ++i) {
      res.push(fn(arr[i], i));
    }
    arr = null;
    return res;
  },
  /** Checks and Return if the prop is Objects own Property */
  hasOwnProp: function(obj, val) {
    return Object.prototype.hasOwnProperty.call(obj, val);
  },
  /** Extend properties from extending Object to initial Object */
  extend: function(newObj, oldObj) {
    if (this.isDefined(newObj) && this.isDefined(oldObj)) {
      for (var prop in oldObj) {
        if (this.hasOwnProp(oldObj, prop)) {
          newObj[prop] = oldObj[prop];
        }
      }
      return newObj;
    } else {
      return newObj || oldObj || {};
    }
  }
};

// This Method will create Multiple functions in the Sys object that can be used to test type of
['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Object', 'Array', 'Undefined']
.forEach(
  function(name) {
    Sys['is' + name] = function(obj) {
      return toString.call(obj) == '[object ' + name + ']';
    };
  }
);
<h1>Use the Helper JavaScript Methods..</h1>
<code>use: if(Sys.isDefined(jQuery){console.log("O Yeah... !!");}</code>

For Exportable CommonJs Module or RequireJS Module....

"use strict";

/*** Helper Utils ***/

/**
 * @description Util file :: From Vault
 * @author Tarandeep Singh
 * @created 2016-08-09
 */

var Sys = {};

Sys = {
    isEmptyObject: function(val){
        return this.isObject(val) && Object.keys(val).length;
    },
    /** This Returns Object Type */
    getType: function(val){
        return Object.prototype.toString.call(val);
    },
    /** This Checks and Return if Object is Defined */
    isDefined: function(val){
        return val !== void 0 || typeof val !== 'undefined';
    },
    /** Run a Map on an Array **/
    map: function(arr,fn){
        var res = [], i=0;
        for( ; i<arr.length; ++i){
            res.push(fn(arr[i], i));
        }
        arr = null;
        return res;
    },
    /** Checks and Return if the prop is Objects own Property */
    hasOwnProp: function(obj, val){
        return Object.prototype.hasOwnProperty.call(obj, val);
    },
    /** Extend properties from extending Object to initial Object */
    extend: function(newObj, oldObj){
        if(this.isDefined(newObj) && this.isDefined(oldObj)){
            for(var prop in oldObj){
                if(this.hasOwnProp(oldObj, prop)){
                    newObj[prop] = oldObj[prop];
                }
            }
            return newObj;
        }else {
            return newObj || oldObj || {};
        }
    }
};

/**
 * This isn't Required but just makes WebStorm color Code Better :D
 * */
Sys.isObject
    = Sys.isArguments
    = Sys.isFunction
    = Sys.isString
    = Sys.isArray
    = Sys.isUndefined
    = Sys.isDate
    = Sys.isNumber
    = Sys.isRegExp
    = "";

/** This Method will create Multiple functions in the Sys object that can be used to test type of **/

['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Object', 'Array', 'Undefined']
    .forEach(
        function(name) {
            Sys['is' + name] = function(obj) {
                return toString.call(obj) == '[object ' + name + ']';
            };
        }
    );


module.exports = Sys;

Currently in Use on a public git repo. Github Project

Now you can import this Sys code in a Sys.js file. then you can use this Sys object functions to find out the type of JavaScript Objects

you can also check is Object is Defined or type is Function or the Object is Empty... etc.

  • Sys.isObject
  • Sys.isArguments
  • Sys.isFunction
  • Sys.isString
  • Sys.isArray
  • Sys.isUndefined
  • Sys.isDate
  • Sys.isNumber
  • Sys.isRegExp

For Example

var m = function(){};
Sys.isObject({});
Sys.isFunction(m);
Sys.isString(m);

console.log(Sys.isDefined(jQuery));
Tarandeep Singh
  • 1,322
  • 16
  • 16
  • 1
    The question asks how to find the type of a *variable*. Your answer shows how to find the type of a *value*. Those are completely different things. – Jörg W Mittag Aug 18 '20 at 12:25
0

Here's a helpful solution:

    newTypeOf = (value) => {
        return Object.prototype.toString.call(value).split(' ')[1].split(']')[0].toString()
    } 

    newTypeOf(12) // Number
    newTypeOf('') // String
    newTypeOf([]) // Array 
    newTypeOf({}) // Number 
    newTypeOf(null) // Null 
    newTypeOf(undefined) // Undefined
    newTypeOf(()=>{}) // Function
Fe3back
  • 924
  • 7
  • 15