JavaScript Data Types Interview Questions & Answers

4 interview angles 10 min read source

JavaScript Data Types Interview Questions & Answers

JavaScript has dynamic typing, which means variables can hold different types of data throughout their lifecycle. Understanding data types is fundamental to writing robust JavaScript code.

Table of Contents


Primitive Data Types

1. What are the primitive data types in JavaScript?

JavaScript has 7 primitive data types:

  1. Number: Represents both integer and floating-point numbers
  2. String: Represents textual data
  3. Boolean: Represents true or false
  4. Undefined: Represents a variable that has been declared but not assigned a value
  5. Null: Represents an intentional absence of any object value
  6. Symbol: Represents a unique identifier (ES6+)
  7. BigInt: Represents integers with arbitrary precision (ES2020+)

Example:

let number = 42;           // Number
let string = "Hello";      // String
let boolean = true;        // Boolean
let undefinedVar;          // Undefined
let nullValue = null;      // Null
let symbol = Symbol();     // Symbol
let bigInt = 123n;         // BigInt

2. What is the difference between primitive and reference types?

Primitive Types Reference Types
Stored directly in memory Stored as references in memory
Immutable (cannot be changed) Mutable (can be changed)
Passed by value Passed by reference
Compared by value Compared by reference

Example:

// Primitive types
let a = 5;
let b = a;  // b gets a copy of a's value
b = 10;     // a remains 5, b becomes 10

// Reference types
let arr1 = [1, 2, 3];
let arr2 = arr1;  // arr2 gets a reference to arr1
arr2.push(4);     // Both arr1 and arr2 are [1, 2, 3, 4]

3. What is the difference between null and undefined?

Null Undefined
Represents intentional absence of value Represents uninitialized variable
Must be explicitly assigned Automatically assigned
Type is “object” (historical bug) Type is “undefined”
Falsy value Falsy value

Example:

let a;                    // undefined
let b = null;            // null
console.log(typeof a);   // "undefined"
console.log(typeof b);   // "object" (historical bug)

// Both are falsy
console.log(Boolean(a)); // false
console.log(Boolean(b)); // false

4. What are the falsy values in JavaScript?

JavaScript has 6 falsy values:

false        // Boolean false
0            // Number zero
-0           // Negative zero
0n           // BigInt zero
""           // Empty string
null         // Null
undefined    // Undefined
NaN          // Not a Number

Example:

if (false) console.log("won't run");
if (0) console.log("won't run");
if ("") console.log("won't run");
if (null) console.log("won't run");
if (undefined) console.log("won't run");
if (NaN) console.log("won't run");

// Everything else is truthy
if ([]) console.log("will run");
if ({}) console.log("will run");
if ("hello") console.log("will run");

5. What is NaN and how do you check for it?

NaN (Not a Number) is a special value that represents an invalid number operation.

Ways to check for NaN:

// Method 1: isNaN() - checks if value is NaN or cannot be converted to number
console.log(isNaN(NaN));        // true
console.log(isNaN("hello"));    // true
console.log(isNaN(42));         // false

// Method 2: Number.isNaN() - only returns true for NaN
console.log(Number.isNaN(NaN));     // true
console.log(Number.isNaN("hello")); // false
console.log(Number.isNaN(42));      // false

// Method 3: Self-comparison (NaN is the only value not equal to itself)
console.log(NaN === NaN);       // false
console.log(NaN !== NaN);       // true

Reference Data Types

6. What are the reference data types in JavaScript?

JavaScript reference types include:

  1. Object: Collection of key-value pairs
  2. Array: Ordered collection of values
  3. Function: Callable object
  4. Date: Date and time representation
  5. RegExp: Regular expression
  6. Map: Key-value collection (ES6+)
  7. Set: Collection of unique values (ES6+)
  8. WeakMap: Weak key-value collection (ES6+)
  9. WeakSet: Weak collection of unique values (ES6+)

Example:

let obj = {};                    // Object
let arr = [];                    // Array
let func = function() {};        // Function
let date = new Date();           // Date
let regex = /pattern/;           // RegExp
let map = new Map();             // Map
let set = new Set();             // Set
let weakMap = new WeakMap();     // WeakMap
let weakSet = new WeakSet();     // WeakSet

7. How do you create objects in JavaScript?

Multiple ways to create objects:

// 1. Object literal
let obj1 = {
    name: "John",
    age: 30
};

// 2. Constructor function
function Person(name, age) {
    this.name = name;
    this.age = age;
}
let obj2 = new Person("John", 30);

// 3. Object.create()
let obj3 = Object.create(null);
obj3.name = "John";

// 4. Class (ES6+)
class PersonClass {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
}
let obj4 = new PersonClass("John", 30);

// 5. Factory function
function createPerson(name, age) {
    return {
        name,
        age,
        greet() {
            return `Hello, I'm ${this.name}`;
        }
    };
}
let obj5 = createPerson("John", 30);

Type Coercion

8. What is type coercion in JavaScript?

Type coercion is the automatic conversion of values from one data type to another when operators are applied to values of different types.

Types of coercion:

  1. Implicit coercion: Automatic conversion
  2. Explicit coercion: Manual conversion

Example:

// Implicit coercion
console.log("5" + 3);        // "53" (string concatenation)
console.log("5" - 3);        // 2 (number subtraction)
console.log("5" * "3");      // 15 (number multiplication)
console.log(true + 1);       // 2 (true becomes 1)

// Explicit coercion
console.log(Number("5"));    // 5
console.log(String(5));      // "5"
console.log(Boolean(1));     // true

9. What are the rules for type coercion with different operators?

Addition operator (+):

// If either operand is a string, convert both to strings and concatenate
console.log("5" + 3);        // "53"
console.log(5 + "3");        // "53"
console.log("5" + "3");      // "53"

// If both are numbers, perform numeric addition
console.log(5 + 3);          // 8

// If one is boolean, convert to number first
console.log(true + 1);       // 2 (true = 1)
console.log(false + 1);      // 1 (false = 0)

*Other arithmetic operators (-, , /, %):

// Convert both operands to numbers
console.log("5" - 3);        // 2
console.log("5" * "3");      // 15
console.log("10" / "2");     // 5
console.log("7" % "3");      // 1

Comparison operators (==, !=):

// Loose equality - allows type coercion
console.log(5 == "5");       // true
console.log(true == 1);      // true
console.log(null == undefined); // true

// Strict equality - no type coercion
console.log(5 === "5");      // false
console.log(true === 1);     // false
console.log(null === undefined); // false

10. What is the difference between == and ===?

== (Loose Equality) === (Strict Equality)
Allows type coercion No type coercion
Compares values after conversion Compares both value and type
Can lead to unexpected results More predictable behavior
Generally not recommended Recommended for most cases

Example:

// Loose equality examples
console.log(5 == "5");           // true
console.log(true == 1);          // true
console.log(null == undefined);  // true
console.log(0 == false);         // true
console.log("" == false);        // true

// Strict equality examples
console.log(5 === "5");          // false
console.log(true === 1);         // false
console.log(null === undefined); // false
console.log(0 === false);        // false
console.log("" === false);       // false

// When they're the same
console.log(5 == 5);             // true
console.log(5 === 5);            // true
console.log("hello" == "hello"); // true
console.log("hello" === "hello"); // true

Type Checking

11. How do you check the type of a value in JavaScript?

Multiple ways to check types:

// 1. typeof operator
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 bug)
console.log(typeof {});              // "object"
console.log(typeof []);              // "object"
console.log(typeof function() {});   // "function"

// 2. instanceof operator (for objects)
console.log([] instanceof Array);    // true
console.log({} instanceof Object);   // true
console.log(function() {} instanceof Function); // true

// 3. Object.prototype.toString.call()
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]"

// 4. Constructor property
console.log([].constructor === Array);    // true
console.log({}.constructor === Object);   // true
console.log("".constructor === String);   // true

12. How do you check if a value is an array?

Multiple ways to check if a value is an array:

let arr = [1, 2, 3];

// Method 1: Array.isArray() (recommended)
console.log(Array.isArray(arr));     // true
console.log(Array.isArray({}));      // false

// Method 2: instanceof
console.log(arr instanceof Array);   // true

// Method 3: constructor property
console.log(arr.constructor === Array); // true

// Method 4: Object.prototype.toString.call()
console.log(Object.prototype.toString.call(arr) === '[object Array]'); // true

// Method 5: typeof + length check (not reliable)
console.log(typeof arr === 'object' && arr.length !== undefined); // true

13. How do you check if a value is a number?

Multiple ways to check if a value is a number:

// Method 1: typeof
function isNumber(value) {
    return typeof value === 'number' && !isNaN(value);
}

// Method 2: Number.isFinite() (recommended)
console.log(Number.isFinite(42));        // true
console.log(Number.isFinite(Infinity));  // false
console.log(Number.isFinite(NaN));       // false
console.log(Number.isFinite("42"));      // false

// Method 3: isFinite() (allows coercion)
console.log(isFinite(42));               // true
console.log(isFinite("42"));             // true
console.log(isFinite(Infinity));         // false
console.log(isFinite(NaN));              // false

// Method 4: Number.isInteger() (for integers only)
console.log(Number.isInteger(42));       // true
console.log(Number.isInteger(42.5));     // false
console.log(Number.isInteger("42"));     // false

Advanced Type Concepts

14. What are Symbols and when would you use them?

Symbols are unique, immutable primitive values that can be used as object property keys.

Key characteristics:

  • Each symbol is unique
  • Cannot be created with new
  • Used as property keys to avoid naming conflicts
  • Not enumerable in for...in loops

Example:

// Creating symbols
const sym1 = Symbol();
const sym2 = Symbol('description');
const sym3 = Symbol('description');

console.log(sym1 === sym2);        // false
console.log(sym2 === sym3);        // false (even with same description)

// Using symbols as object keys
const obj = {
    [sym1]: 'value1',
    [sym2]: 'value2'
};

console.log(obj[sym1]);            // 'value1'
console.log(Object.keys(obj));     // [] (symbols are not enumerable)
console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(), Symbol(description)]

// Well-known symbols
const arr = [1, 2, 3];
console.log(arr[Symbol.iterator]); // function (iterator method)

15. What is BigInt and when would you use it?

BigInt is a built-in object that provides a way to represent whole numbers larger than 2^53 - 1.

Key characteristics:

  • Cannot be mixed with regular numbers in arithmetic
  • Created by appending n to an integer or using BigInt()
  • Useful for large integer calculations

Example:

// Creating BigInts
const bigInt1 = 1234567890123456789012345678901234567890n;
const bigInt2 = BigInt("1234567890123456789012345678901234567890");

// Arithmetic operations
console.log(bigInt1 + bigInt2);    // 2469135780246913578024691357802469135780n
console.log(bigInt1 * 2n);         // 2469135780246913578024691357802469135780n

// Cannot mix with regular numbers
// console.log(bigInt1 + 1);       // TypeError
console.log(bigInt1 + 1n);         // OK

// Comparison works
console.log(1n < 2);               // true
console.log(2n > 1);               // true
console.log(1n == 1);              // true
console.log(1n === 1);             // false (different types)

16. What is the difference between shallow and deep copying?

Shallow Copy: Creates a new object but references the same nested objects. Deep Copy: Creates a completely independent copy of the object and all nested objects.

Example:

const original = {
    name: "John",
    age: 30,
    address: {
        city: "New York",
        country: "USA"
    }
};

// Shallow copy
const shallowCopy = { ...original };
// or
const shallowCopy2 = Object.assign({}, original);

// Deep copy
const deepCopy = JSON.parse(JSON.stringify(original));
// or using structuredClone (modern browsers)
const deepCopy2 = structuredClone(original);

// Testing the difference
shallowCopy.address.city = "Los Angeles";
console.log(original.address.city);    // "Los Angeles" (changed)
console.log(shallowCopy.address.city); // "Los Angeles"

deepCopy.address.city = "Chicago";
console.log(original.address.city);    // "Los Angeles" (unchanged)
console.log(deepCopy.address.city);    // "Chicago"

17. What is the difference between let, const, and var?

Feature var let const
Scope Function-scoped Block-scoped Block-scoped
Hoisting Hoisted to top Not hoisted Not hoisted
Reassignment Can be reassigned Can be reassigned Cannot be reassigned
Initialization Can be declared without initialization Can be declared without initialization Must be initialized

Example:

// var - function scoped, hoisted
function example() {
    console.log(x); // undefined (hoisted but not initialized)
    var x = 5;
    if (true) {
        var y = 10;
    }
    console.log(y); // 10 (accessible outside block)
}

// let - block scoped, not hoisted
function example2() {
    // console.log(x); // ReferenceError (not hoisted)
    let x = 5;
    if (true) {
        let y = 10;
        console.log(y); // 10
    }
    // console.log(y); // ReferenceError (block scoped)
}

// const - block scoped, must be initialized
const PI = 3.14159;
// PI = 3.14; // TypeError (cannot reassign)

const obj = { name: "John" };
obj.name = "Jane"; // OK (object properties can be changed)
// obj = {}; // TypeError (cannot reassign the reference)

Additional Resources


Understanding JavaScript data types is fundamental to writing robust and predictable code. Practice these concepts to master type handling in JavaScript.

Interview angle

  • “What are the primitive types?” - string, number, boolean, null, undefined, symbol, bigint. Everything else is an object. Primitives are immutable and compared by value; objects by reference.
  • null or undefined?” - undefined means “not assigned”; null means “deliberately empty”. typeof null returning "object" is a famous bug kept for compatibility. Use ?? and ?., which treat only these two as absent, rather than ||, which also swallows 0 and "".
  • “Why is 0.1 + 0.2 !== 0.3?” - IEEE 754 doubles cannot represent those decimals exactly. Compare with an epsilon, or use integers of the smallest unit (cents) for money. BigInt gives arbitrary-precision integers but not decimals.
  • == or ===?” - always ===, with the single idiomatic exception of x == null to test both null and undefined. The coercion table for == is not something anyone should have to reason about.