NeuroAgent

How to Check if Variable is String in JavaScript

Learn the best methods to check if a variable is a string in JavaScript. Compare typeof, instanceof, and Object.prototype.toString() approaches with practical examples and performance considerations.

Question

How can I determine whether a variable is a string or something else in JavaScript?

NeuroAgent

The most reliable ways to check if a variable is a string in JavaScript include using the typeof operator, instanceof operator, and Object.prototype.toString.call() method. Each approach has different strengths and use cases depending on your specific needs and the JavaScript environment you’re working with.

Contents

typeof Operator

The typeof operator is the most straightforward method for checking if a variable is a string. It returns a string indicating the type of the unevaluated operand.

javascript
let myString = "Hello, World!";
let myNumber = 42;
let myObject = {};
let myNull = null;
let myUndefined = undefined;

console.log(typeof myString);      // "string"
console.log(typeof myNumber);      // "number"
console.log(typeof myObject);      // "object"
console.log(typeof myNull);        // "object" (this is a known quirk)
console.log(typeof myUndefined);   // "undefined"

Advantages:

  • Simple and fast
  • Works with primitive values and objects
  • No need to call any methods

Disadvantages:

  • typeof null returns "object" (this is a well-known bug in JavaScript)
  • Can be confused with boxed string objects
javascript
let boxedString = new String("Hello");
console.log(typeof boxedString);   // "object"

instanceof Operator

The instanceof operator tests whether an object has in its prototype chain the prototype property of a constructor. For primitive strings, you need to use the String constructor.

javascript
let myString = "Hello, World!";
let myBoxedString = new String("Hello");

console.log(myString instanceof String);      // false (primitive is not instance of String)
console.log(myBoxedString instanceof String); // true (boxed string is instance of String)

// For primitive strings, you can use:
console.log(myString instanceof Object);      // false (primitives are not objects)

Advantages:

  • Works well with object instances
  • Can be extended in prototype chains

Disadvantages:

  • Doesn’t work well with primitive strings
  • Can be manipulated by changing prototype chains
  • Returns false for primitive values

Object.prototype.toString.call() Method

This method is the most reliable way to check types, including strings. It returns a string representing the object’s type.

javascript
let myString = "Hello, World!";
let myBoxedString = new String("Hello");
let myNumber = 42;
let myObject = {};

console.log(Object.prototype.toString.call(myString));      // "[object String]"
console.log(Object.prototype.toString.call(myBoxedString)); // "[object String]"
console.log(Object.prototype.toString.call(myNumber));      // "[object Number]"
console.log(Object.prototype.toString.call(myObject));      // "[object Object]"

Advantages:

  • Works with both primitive and boxed strings
  • Consistent across different JavaScript environments
  • Not affected by prototype manipulation

Disadvantages:

  • More verbose than typeof
  • Slightly slower performance
  • Returns a string that needs to be checked
javascript
function isString(value) {
  return Object.prototype.toString.call(value) === '[object String]';
}

console.log(isString("Hello"));       // true
console.log(isString(new String("Hi"))); // true
console.log(isString(42));            // false

String Constructor Check

You can also check if a value is a string by comparing it to the String constructor or using the String() function.

javascript
let myString = "Hello, World!";
let myBoxedString = new String("Hello");

console.log(myString.constructor === String);      // true
console.log(myBoxedString.constructor === String); // true

// Using String() constructor
console.log(myString instanceof String);            // false (primitive)
console.log(myBoxedString instanceof String);       // true (boxed)

Important note: This method fails for null and undefined values because they don’t have a constructor property.

javascript
let myNull = null;
let myUndefined = undefined;

console.log(myNull?.constructor === String);    // TypeError: Cannot read properties of null
console.log(myUndefined?.constructor === String); // TypeError: Cannot read properties of undefined

Comparing Methods

Here’s a comparison table of the different methods:

Method Primitive String Boxed String Null Undefined Performance
typeof "string" "object" "object" "undefined" Fastest
instanceof String false true false false Fast
Object.prototype.toString.call() "[object String]" "[object String]" "[object Null]" "[object Undefined]" Medium
constructor === String true true ❌ Error ❌ Error Fast

Practical Examples

Basic Type Checking Function

javascript
function isString(value) {
  return typeof value === 'string';
}

console.log(isString("hello"));    // true
console.log(isString(123));        // false
console.log(isString(null));       // false
console.log(isString(undefined));  // false

Comprehensive Type Checking Function

javascript
function isString(value) {
  // Most reliable method
  return Object.prototype.toString.call(value) === '[object String]';
}

// Alternative using typeof (faster but less comprehensive)
function isStringFast(value) {
  return typeof value === 'string';
}

// Test with various types
console.log(isString("hello"));           // true
console.log(isString(new String("hi")));  // true
console.log(isString(42));               // false
console.log(isString(null));              // false
console.log(isString(undefined));         // false
console.log(isString({}));               // false
console.log(isString([]));               // false

Handling Null and Undefined Safely

javascript
function safeIsString(value) {
  if (value === null || value === undefined) {
    return false;
  }
  return typeof value === 'string';
}

// Or using optional chaining
function safeIsStringModern(value) {
  return typeof value?.constructor === 'function' && 
         value.constructor === String;
}

Edge Cases and Considerations

String Objects vs Primitive Strings

javascript
let primitive = "hello";
let boxed = new String("hello");

console.log(typeof primitive);    // "string"
console.log(typeof boxed);        // "object"
console.log(primitive === boxed); // false

Cross-Environment Compatibility

Different JavaScript environments might have different behaviors:

javascript
// Node.js vs Browser differences
console.log(typeof document); // "object" in browser, "undefined" in Node.js
console.log(typeof window);   // "object" in browser, "undefined" in Node.js

Performance Considerations

For performance-critical code, typeof is the fastest option:

javascript
// Benchmark different methods
console.time('typeof');
for (let i = 0; i < 1000000; i++) {
  typeof "test" === "string";
}
console.timeEnd('typeof');

console.time('toString');
for (let i = 0; i < 1000000; i++) {
  Object.prototype.toString.call("test") === "[object String]";
}
console.timeEnd('toString');

Security Considerations

Be aware that instanceof can be manipulated:

javascript
// Malicious code could modify String.prototype
String.prototype.valueOf = function() { return {}; };

let s = "hello";
console.log(s instanceof String); // true (but dangerous!)

Sources

  1. MDN Web Docs - typeof operator
  2. MDN Web Docs - instanceof operator
  3. MDN Web Docs - Object.prototype.toString()
  4. ECMAScript Language Specification - typeof operator
  5. JavaScript.info - Type conversions

Conclusion

  • The typeof operator is the simplest and fastest method for checking primitive strings, but fails for boxed strings and has the null quirk
  • Object.prototype.toString.call() is the most reliable method that works consistently for both primitive and boxed strings, but is more verbose
  • instanceof String only works with boxed string objects and returns false for primitive strings
  • For most use cases, typeof value === 'string' provides the best balance of simplicity and performance
  • Consider your specific needs: if you need to handle boxed strings or require maximum reliability, use Object.prototype.toString.call(value) === '[object String]'
  • Always consider the JavaScript environment and potential prototype manipulation when choosing your type-checking method

Choose the method that best fits your specific requirements, keeping in mind performance, reliability, and the types of values you need to handle.