Understanding Type Checking in JavaScript Using typeof
In JavaScript, the type checking operator typeof returns the data type of the argument that was supplied to it. Any variable, function, or object whose type you want to determine using the typeof operator can be used as the operand.
The typeof operator can be used to check the data type before execution because JavaScript is a dynamically typed language, which means that you do not need to define the type of variables when declaring them.
JavaScript type checking can frequently be annoying, especially for inexperienced JS developers. We aim to help you check types in JS more accurately and gain a better understanding of them. The typeof operator, shadow objects/coercion, objects, primitives, and how to securely obtain a "real" JavaScript type are all covered in this article.
We will cover the following:
- Data Types in JavaScript
- JavaScript Operator Type
- Using Typeof in JavaScript with Various Operands
- Basic Type Checking Using typeof
- Better Type Checking in JavaScript
- Common JavaScript typeof Use Cases
Data Types in JavaScript
It's vital to take a quick look at the JavaScript data types before discussing type checking using typeof. Although the JavaScript data types are not covered in length in this article, you can learn a few things as you go.
JavaScript had six data types before ES6. A new type named Symbol was included in the ES6 specification. The types are listed below:
- String
- Number
- Boolean (the values true and false)
- null (the value null)
- undefined (the value undefined)
- Symbol
- Object
Primitive types refer to the initial six data types. Other than the first six data types, all other data types are objects and can be referred to as reference types. A collection of properties in the form of name and value pairs forms an object type.
As you can see from the list, the primitive JavaScript data types null and undefined are both data types with a single value.
What about arrays, functions, regular expressions, etc.? You might start to question. Each of them is a unique type of thing.
An array is a particular type of object that consists of an ordered group of numeric values and has unique syntax and properties that make dealing with it different from working with other types of objects.
A function is a unique type of object that is connected to an executable script block. The function is called to run the script block. It differs from other typical objects in that it also has unique syntax and qualities.
There are numerous object class constructors in JavaScript for constructing different types of objects, including:
- Date - for creating date objects
- RegExp - for creating regular expressions
- Error - for creating JavaScript errors
JavaScript Operator Type
The type of operator only accepts a single operand (a unary operator). It determines the operand's type and then returns the outcome as a string. This is how you employ it to determine the kind of the number 001.
typeof 001; // returns 'number'
The typeof operator has an alternate syntax that allows you to utilize it like a function:
typeof(operand)
This syntax is helpful when evaluating an expression rather than a single value. Here is an illustration of that:
typeof(typeof 001); // returns 'string'
The string "number" is returned when the expression typeof 001 evaluates to the type number in the example above. The output of typeof("number") is then "string."
Using Typeof in JavaScript with Various Operands
We'll examine a few instances where the typeof operator in JavaScript is used to determine the data types of each of the above operands.
To Check Number Data Type
Here, we'll utilize the typeof operator with numbers as operands to log the outcome to the console. As operands, we'll employ positive, negative, zero, floating-point numbers, infinity, NaN, and math equations.
The idea will also be applied to explicitly typecasting, parsing, and using a string as an operand after converting it to an integer or float. The use of each of these operands is seen in the code below.
console.log(typeof 12)
console.log(typeof -31)
console.log(typeof 0)
console.log(typeof 5.695)
console.log(typeof Infinity)
// Although NaN is Not-a-Number, it returns a number
console.log(typeof NaN)
console.log(typeof Math.LN2)
// Explicitly typecasting to number
console.log(typeof Number(`7`))
// Even if the value cannot be typecasted to integer, the result is a number
console.log(typeof Number(`Simplilearn`))
console.log(typeof parseInt(`86`))
console.log(typeof parseFloat(`40.05`))
Output:
number
number
number
number
number
number
number
number
number
number
number
To Check String Data Type
We shall pass string operands in this case. As a result of an empty string, a string of characters, a string of multiple words, numbers enclosed in quotes, the use of typeof, and conversions using the String function, the typeof in JavaScript will always return "string."
console.log(typeof '');
console.log(typeof 'Simplilearn');
console.log(typeof 'Welcome to JavaScript Tutorials');
console.log(typeof '10');
// typeof will always return a string as a result
console.log(typeof(typeof 15));
// Using String function, which is safer than toString conversion
console.log(typeof String(20));
Output:
string
string
string
string
string
string
To Check Undefined Data Type
This example will demonstrate how to check for undefined operand types in JavaScript using typeof. We'll record the outcome to the console while using the undefined keyword, a declared but undefined variable, and an undefined variable as operands.
It's important to note that we are using Null and not null in this case because the former returns undefined and the latter returns object as the operands' type.
// undefined keyword
console.log(typeof undefined)
// Declared but undefined variable
let a
console.log(typeof a);
// Undefined variable
console.log(typeof v);
Output:
undefined
undefined
undefined
To Check Boolean Data Type
Boolean values will be used as operands in this example. JavaScript's typeof function returns boolean for values that are explicitly typecast as boolean using the Boolean() function when the value is true/false and two "!" operators are being used.
console.log(typeof true);
console.log(typeof false);
console.log(typeof Boolean(1));
console.log(typeof !!(1));
Output:
boolean
boolean
boolean
boolean
To Check Object Data Type
The JavaScript code below uses typeof to pass objects as operands. The object will be returned as a result of the following operands.
console.log(typeof null);
console.log(typeof [1, 2, 'hello']);
console.log(typeof {a: 'hello', b: 'welcome'});
console.log(typeof [1, 2, 3, 4]);
Output:
object
object
object
object
To Check Symbol Data Type
We'll utilize the symbol data type operands in this example. When we supply an empty Symbol() function, a Symbol() function with a single parameter, and Symbol.iterator, the JavaScript typeof operator will return "symbol".
console.log(typeof Symbol());
console.log(typeof Symbol('parameter'));
console.log(typeof Symbol.iterator);
Output:
symbol
symbol
symbol
To Check Function Data Type
When we send the operands to typeof in JavaScript in this example, the output will be "function". When we pass a class, a predefined function, or a user-defined function as an operand, the typeof operator will produce the result as a function.
console.log(typeof function() {});
console.log(typeof Math.tan);
console.log(typeof class C {});
Output:
function
function
function
Basic Type Checking Using typeof
Syntax
The typeof operator in JavaScript evaluates to a string indicating the type of its operand and is a unary operator (takes only one operand). It is positioned before its operand, separated by a space, just like other unary operators:
typeof 75; // "number"
By enclosing its operand in parentheses, a different syntax exists that enables you to use typeof like a function call. This is quite helpful for type checking the result that JavaScript expressions return:
typeof(typeof 75); // "string"
Error Safety
Before ES6, no matter the operand, the typeof operator always returned a string.
When an identifier is not declared, typeof will return "undefined" rather than raising a ReferenceError.
console.log(undeclaredVariable === undefined); // ReferenceError
console.log(typeof undeclaredVariable === 'undefined'); // true
However, in ES6, if block-scoped variables created with the let or const keywords are used with the typeof operator before they have been initialized, a ReferenceError will still be raised. This is due to block-scoped variables.
Until they are initialized, block-scoped variables are in the temporal dead zone:
console.log(typeof tdzVariable === 'undefined'); // ReferenceError
const tdzVariable = 'I am initialized.';
Better Type Checking in JavaScript
The results of the type tests in the preceding section show that some values will need further checks to further identify them.
For instance, when the type check is performed using the typeof operator, null and [] will both be of the "object" type.
By relying on a few different qualities, extra checks on the value can be made:
- Using the instanceof operator
- Checking the constructor property of the object
- Determine the object class using the toString() method of the object
Checking for null
As you have already shown, there is no benefit to checking for a "null" value using the typeof operator. As seen in the following code snippet, the easiest technique to check for a "null" value is to perform a strict equality comparison of the value against the null keyword.
function isNull(value) {
return value === null;
}
Here, it's crucial to apply the strict equality operator (===). This significance is demonstrated by the undefined value in the following snippet of code:
console.log(undefined == null); // true
console.log(undefined === null); // false
Checking for NaN
When arithmetic operations produce undefined values that cannot be represented, NaN is a special value that is returned.
For instance, (0 / 0) => NaN.
NaN is the outcome when an attempt is made to convert a non-numeric value that lacks a primitive number representation to a number.
Any calculation involving NaN will invariably result is NaN. You should ensure that a value is not NaN if you want to utilize it in any way involving arithmetic.
The typeof operator returns "number" when used to check for NaN values. Use the Number instead of the global isNaN() function to check for NaN values. The ES6 isNaN() method was added:
console.log(isNaN(NaN)); // true
console.log(isNaN(null)); // false
console.log(isNaN(undefined)); // true
console.log(isNaN(Infinity)); // false
console.log(Number.isNaN(NaN)); // true
console.log(Number.isNaN(null)); // false
console.log(Number.isNaN(undefined)); // false
console.log(Number.isNaN(Infinity)); // false
The NaN value has a highly unique quality. It is the only JavaScript value that, in comparison to other values, never equals any other value, not even itself:
var x = NaN;
console.log(x == NaN); // false
console.log(x === NaN); // false
Following are some ways to check for NaN:
function isNan(value) {
return value !== value;
}
The above function can be used as a polyfill in non-ES6 environments as follows because it implements Number.isNaN() in a way that is very similar to that added in ES6:
Number.isNaN = Number.isNaN || (function(value) {
return value !== value;
})
Last but not least, you can use the Object.is() function introduced in ES6 to determine whether a value is NaN. If two values are the same, the Object.is() function determines whether they are:
function isNan(value) {
return Object.is(value, Number.NaN);
}
Checking for Arrays
When checking for an array using typeof, the result is "object". As demonstrated in this code sample, there are numerous techniques to more effectively check for an array:
Method 1: Constructor Property
// Not reliable
function isArray(value) {
return typeof value == 'object' && value.constructor === Array;
}
Method 2: instanceof
// Not reliable since an object's prototype can be changed
// Unexpected results within frames
function isArray(value) {
return value instanceof Array;
}
Method 3: Object.prototype.toString()
// Better option and very similar to ES6 Array.isArray()
function isArray(value) {
return Object.prototype.toString.call(value) === '[object Array]';
}
Method 4: ES6 Array.isArray()
function isArray(value) {
return Array.isArray(value);
}
Generic Type Checking
The Object.prototype.toString() method can be quite helpful for determining the object type of any JavaScript variable, as was demonstrated with arrays.
It returns the object type in the format: [object Type], where Type is the object type when it is called on a value using call() or apply().
Look at the following sample of code:
function type(value) {
var regex = /^[object (S+?)]$/;
var matches = Object.prototype.toString.call(value).match(regex) || [];
return(matches[1] || 'undefined').toLowerCase();
}
Results of type checking using the recently developed type() function are displayed in the code snippet below:
console.log(type('')); // "string"
console.log(type('hello')); // "string"
console.log(type(String('hello'))); // "string"
console.log(type(new String('hello'))); // "string"
console.log(type(0)); // "number"
console.log(type(-0)); // "number"
console.log(type(0xff)); // "number"
console.log(type(-3.142)); // "number"
console.log(type(Infinity)); // "number"
console.log(type(-Infinity)); // "number"
console.log(type(NaN)); // "number"
console.log(type(Number(75))); // "number"
console.log(type(new Number(75))); // "number"
console.log(type(true)); // "boolean"
console.log(type(false)); // "boolean"
console.log(type(new Boolean(true))); // "boolean"
console.log(type(undefined)); // "undefined"
console.log(type(null)); // "null"
console.log(type(Symbol())); // "symbol"
console.log(type(Symbol.species)); // "symbol"
console.log(type([])); // "array"
console.log(type(Array(5))); // "array"
console.log((function() { return type(arguments) })()); // "arguments"
console.log(type(function() {})); // "function"
console.log(type(new Function)); // "function"
console.log(type(class {})); // "function"
console.log(type({})); // "object"
console.log(type(new Object)); // "object"
console.log(type(/^(.+)$/)); // "regexp"
console.log(type(new RegExp("^(.+)$"))); // "regexp"
console.log(type(new Date)); // "date"
console.log(type(new Set)); // "set"
console.log(type(new Map)); // "map"
console.log(type(new WeakSet)); // "weakset"
console.log(type(new WeakMap)); // "weakmap"
Common JavaScript typeof Use Cases
The following are a few of the most typical JavaScript usage for typeof:
- Type checking while a function accepts parameters. The example below will help you understand.
In the example, a function to multiply two numbers is declared and defined. To determine whether the parameters provided to the function are integers or not, use the typeof operator. The initial code asks for integer numbers and returns the desired outcome.
function multiply(x, y) {
// Type-checking
if(typeof x !== 'number' || typeof y !== 'number') {
throw new Error('Arguments must be a number');
};
return x * y;
}
console.log(multiply(2, 5))
Output:
10
As you can see, we succeeded in this code by passing 2 and 5, and the result was 10.
Let's mix a string and an integer now, and then log the outcome to the terminal. On the other hand, this code will pass both an integer and a text and get the error message.
function multiply(x, y) {
// Type-checking
if(typeof x !== 'number' || typeof y !== 'number') {
throw new Error('Arguments must be a number');
};
return x * y;
}
console.log(multiply(2, 'hello'))
Output:
error: Uncaught Arguments must be a number
- Checking whether a variable is defined, or checking existence, is another usage of the JavaScript typeof operator.
Here, we'll write a function to add two numbers while determining whether or not both variables are defined.
let x = 20;
let y;
function sum(x, y) {
// Checking existence
if(typeof x === 'undefined') {
throw new Error('x is undefined');
};
if(typeof y === 'undefined') {
throw new Error('y is undefined');
}
return x + y;
}
console.log(sum(x, y))
Output:
error: Uncaught y is undefined
Wrap Up!!!
You have learned a little bit about the JavaScript type system, its data types, and how type checking can be done using the typeof operator in this article.
Although the JavaScript type checking keyword typeof is helpful, there are certain limitations related to old flaws. The majority of the primitive types in JavaScript, including undefined, string, and integer, benefit greatly from type checking with typeof.
Array, Date, and Regular Expressions, on the other hand, are native objects that are not differentiated from one another by typeof and all return "object," along with null, unexpectedly.
To sum up, typeof is an imperfect but powerful tool to check a typeof value.
Monitor Your JavaScript Applications with Atatus
Atatus keeps track of your JavaScript application to give you a complete picture of your clients' end-user experience. You can determine the source of delayed response times, database queries, and other issues by identifying backend performance bottlenecks for each API request.
To make bug fixing easier, every JavaScript error is captured with a full stack trace and the specific line of source code marked. To assist you in resolving the JavaScript error, look at the user activities, console logs, and all JavaScript requests that occurred at the moment. Error and exception alerts can be sent by email, Slack, PagerDuty, or webhooks.
#1 Solution for Logs, Traces & Metrics
APM
Kubernetes
Logs
Synthetics
RUM
Serverless
Security
More