How to write isNumber() in JavaScript?

Learn how to write isnumber() in javascript? with practical examples, diagrams, and best practices. Covers javascript development techniques with visual explanations.

Mastering isNumber(): Robust Number Validation in JavaScript

Hero image for How to write isNumber() in JavaScript?

Learn various techniques to reliably check if a variable is a number in JavaScript, covering primitive types, objects, and edge cases.

Determining if a given variable is a number in JavaScript might seem straightforward, but the language's flexible type system introduces several nuances. From primitive numbers to Number objects, and special values like NaN and Infinity, a robust isNumber() function needs to handle various scenarios. This article explores different approaches, their strengths, and their weaknesses, helping you write reliable number validation logic.

The Basic Approach: typeof Operator

The typeof operator is the most direct way to check the primitive type of a variable. When applied to a number, it returns the string 'number'. This works well for literal numbers and variables holding numeric values.

function isNumberBasic(value) {
  return typeof value === 'number';
}

console.log(isNumberBasic(123));        // true
console.log(isNumberBasic(3.14));       // true
console.log(isNumberBasic(-5));         // true
console.log(isNumberBasic('hello'));    // false
console.log(isNumberBasic(true));       // false
console.log(isNumberBasic(null));       // false
console.log(isNumberBasic(undefined));  // false

Basic isNumber check using typeof.

Handling NaN and Infinity

For a more robust isNumber() function, you often need to exclude NaN and Infinity. JavaScript provides Number.isNaN() and Number.isFinite() for this purpose. Number.isNaN() is preferred over the global isNaN() because the global version attempts to coerce its argument to a number, leading to unexpected results (e.g., isNaN('hello') is true). Number.isFinite() checks if a value is a finite number, excluding NaN, Infinity, and -Infinity.

function isNumberRobust(value) {
  return typeof value === 'number' && Number.isFinite(value);
}

console.log(isNumberRobust(123));        // true
console.log(isNumberRobust(3.14));       // true
console.log(isNumberRobust(-5));         // true
console.log(isNumberRobust(NaN));        // false
console.log(isNumberRobust(Infinity));   // false
console.log(isNumberRobust(-Infinity));  // false
console.log(isNumberRobust('123'));      // false (still not a number primitive)

Robust isNumber check excluding NaN and Infinity.

flowchart TD
    A[Start: Check value] --> B{Is typeof value === 'number'?}
    B -- No --> D[Result: false]
    B -- Yes --> C{Is Number.isFinite(value)?}
    C -- No --> D
    C -- Yes --> E[Result: true]

Decision flow for a robust isNumber function.

Considering Number Objects and Type Coercion

JavaScript also has a Number object wrapper (new Number(123)). While typeof new Number(123) returns 'object', you might want to treat these as numbers. Additionally, sometimes you might want to check if a value can be coerced into a valid number (e.g., a string like '123').

function isNumberCoercible(value) {
  if (typeof value === 'number' && Number.isFinite(value)) {
    return true;
  }
  // Handle Number objects
  if (value instanceof Number && Number.isFinite(value.valueOf())) {
    return true;
  }
  // Attempt coercion for strings
  if (typeof value === 'string' && value.trim() !== '') {
    const coerced = Number(value);
    return Number.isFinite(coerced);
  }
  return false;
}

console.log(isNumberCoercible(123));           // true
console.log(isNumberCoercible(new Number(456))); // true
console.log(isNumberCoercible('789'));         // true
console.log(isNumberCoercible('  10.5  '));    // true
console.log(isNumberCoercible('abc'));         // false
console.log(isNumberCoercible(null));          // false
console.log(isNumberCoercible(true));          // false
console.log(isNumberCoercible(''));            // false

An isNumber function that handles Number objects and coercible strings.

Summary of Approaches

Choosing the right isNumber() implementation depends on your specific requirements. Here's a quick overview:

Hero image for How to write isNumber() in JavaScript?

Comparison of different isNumber implementations.

Basic (typeof)

function isNumberBasic(value) {
  return typeof value === 'number';
}
// Handles primitive numbers, but includes NaN and Infinity.

Robust (typeof + isFinite)

function isNumberRobust(value) {
  return typeof value === 'number' && Number.isFinite(value);
}
// Best for strict numeric validation, excludes NaN and Infinity.

Coercible (Advanced)

function isNumberCoercible(value) {
  if (typeof value === 'number' && Number.isFinite(value)) return true;
  if (value instanceof Number && Number.isFinite(value.valueOf())) return true;
  if (typeof value === 'string' && value.trim() !== '') {
    const coerced = Number(value);
    return Number.isFinite(coerced);
  }
  return false;
}
// Useful for user input, handles Number objects and coercible strings.