In JavaScript, you will sometimes need to identify the type of an object or variable at runtime.
JavaScript is a dynamically typed language, which means that the type of a variable is determined and can change during program execution.
Due to this flexibility, it’s not always straightforward to determine the exact type of a value. Let’s look at the different options 👇.
Methods to Determine Type in JavaScript
In JavaScript, there are different methods to identify the type of an object or variable. The choice of method depends on the use case (and the level of precision you need).
| Method | Use Cases | Limitations |
|---|---|---|
typeof | Primitive values, functions | Does not distinguish arrays from objects |
instanceof | Prototype relationships | Fails in multiple environments |
Object.prototype.toString | Specific types | Verbose, requires extra call |
constructor | Custom classes and objects | Can be overridden |
prototype.name | Identify custom classes | Not universal |
Check Primitive Values with typeof
The typeof operator is the simplest and most common method for determining the type of a variable. It returns a string indicating the type of the evaluated value.
typeof value;
For example,
console.log(typeof 42); // "number"
console.log(typeof "Hello"); // "string"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
console.log(typeof null); // "object" (historical quirk)
console.log(typeof {}); // "object"
console.log(typeof []); // "object" (but it is an array)
console.log(typeof function(){}); // "function"
typeofis useful for primitive values (numbers, strings, booleans, etc.).- It identifies functions as
function. - It does not distinguish between
null, general objects ({}), and arrays ([]), which limits its usefulness in certain cases.
Check if it’s an Instance of a Class with instanceof
The instanceof operator verifies if an object is an instance of a class or if it inherits from its prototype.
object instanceof Class;
For example,
class Person {}
const juan = new Person();
console.log(juan instanceof Person); // true
console.log([] instanceof Array); // true
console.log({} instanceof Object); // true
- It only works with objects, not with primitive values.
- It’s useful for identifying custom classes or inheritance hierarchies.
- It cannot detect the type of primitive values like
stringornumber.
Caution:
If you work with multiple environments (e.g., iframes), instanceof can fail because the prototypes of objects in different contexts are different.
Identify Specific Types with Object.prototype
The Object.prototype.toString() method is a quite useful technique for determining the type of an object.
Syntax:
Object.prototype.toString.call(value);
This method will always return a string in the form [object Type]. For example,
console.log(Object.prototype.toString.call(42)); // "[object Number]"
console.log(Object.prototype.toString.call("Hello")); // "[object String]"
console.log(Object.prototype.toString.call([])); // "[object Array]"
console.log(Object.prototype.toString.call({})); // "[object Object]"
console.log(Object.prototype.toString.call(null)); // "[object Null]"
console.log(Object.prototype.toString.call(undefined)); // "[object Undefined]"
console.log(Object.prototype.toString.call(function(){})); // "[object Function]"
console.log(Object.prototype.toString.call(new Date())); // "[object Date]"
- It’s more reliable than
typeoffor distinguishing between objects, arrays, andnull. - It’s commonly used to detect special types like
Date,RegExp, orError.
Check the Constructor with constructor
Another way is to use the constructor property of an object, which refers to the constructor function that created it.
object.constructor;
This can be useful for identifying custom types. For example,
const date = new Date();
console.log(date.constructor === Date); // true
const myArray = [];
console.log(myArray.constructor === Array); // true
- If the
constructorproperty is overwritten, this method is not reliable. - It doesn’t work with primitive values.
Identify the Prototype with prototype.name
Some prototypes (like those created with custom classes) have a name property that indicates their type.
This is useful when we want to identify among custom classes (like the ones we created ourselves). For example,
// here would go your class definition
class Vehicle { }
const car = new Vehicle();
console.log(car.constructor.name); // "Vehicle"
- It only works with custom classes or explicitly defined constructors.
Combining Methods
In practice, it will sometimes be necessary to combine multiple methods to identify types with greater precision.
For example, you can use typeof for primitive values and Object.prototype.toString for complex objects:
function getType(value) {
if (typeof value === "object") {
if (value === null) return "null";
if (Array.isArray(value)) return "array";
return Object.prototype.toString.call(value).slice(8, -1).toLowerCase();
}
return typeof value;
}
console.log(getType(42)); // "number"
console.log(getType("Hello")); // "string"
console.log(getType([])); // "array"
console.log(getType({})); // "object"
console.log(getType(null)); // "null"
console.log(getType(undefined)); // "undefined"
Here,
- First we use
typeofto determine if the object is primitive - We also manually handle the
nulltype - Finally, we use
prototypefor the remaining cases (slice(8, -1)removes[objectand the last]from the string)
