JavaScript Data Types Complete Guide

JavaScript Data Types Overview

JavaScript has dynamic types - variables can hold different data types. There are two main categories: Primitive Types and Object Types.

Type Categories

  • Primitive Types - Basic immutable values stored directly in memory
  • Reference Types - Objects stored by reference, can contain multiple values
  • Dynamic Typing - Variables can change types during execution
  • Type Coercion - Automatic type conversion in operations

Primitive Data Types

Primitive types are the basic building blocks in JavaScript. They are immutable and stored by value.

javascript
1// String - textual data
2const userName = "John Doe";
3const message = 'Hello World';
4const template = `Hello ${userName}`;
5
6// Number - integers and floating points
7const age = 30;
8const price = 19.99;
9const negative = -45;
10const scientific = 2.5e4; // 25000
11
12// Boolean - true/false values
13const isActive = true;
14const hasPermission = false;
15
16// Undefined - declared but not assigned
17let undefinedVar;
18let anotherUndefined = undefined;
19
20// Null - intentional empty value
21const emptyValue = null;
22const user = null;
23
24// Symbol - unique identifiers
25const id = Symbol('id');
26const key = Symbol('key');
27
28// BigInt - large integers
29const bigNumber = 9007199254740991n;
30const huge = 123456789012345678901234567890n;

Primitive Characteristics

  • Immutable - Cannot be changed after creation
  • Stored by Value - Direct value stored in memory
  • No Methods - Primitives themselves have no methods
  • Fast Access - Quick memory access and comparison

Object Data Types

Objects are reference types that can store collections of data and functionality. They are mutable and stored by reference.

javascript
1// Object - key-value pairs
2const person = {
3    firstName: "John",
4    lastName: "Doe",
5    age: 30,
6    isStudent: false,
7    address: {
8        street: "123 Main St",
9        city: "Boston"
10    }
11};
12
13// Array - ordered lists
14const fruits = ["apple", "banana", "orange"];
15const mixedArray = [1, "hello", true, null];
16const matrix = [[1, 2], [3, 4]];
17
18// Function - reusable code blocks
19function greet(name) {
20    return `Hello, ${name}!`;
21}
22
23const multiply = function(a, b) {
24    return a * b;
25};
26
27const arrowFunc = (x, y) => x + y;
28
29// Date - date and time
30const now = new Date();
31const birthday = new Date('1990-05-15');
32
33// Regular Expression - pattern matching
34const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
35const digitPattern = /\d+/g;
36
37// Special objects
38const map = new Map();
39const set = new Set();
40const promise = new Promise(() => {});

Object Characteristics

  • Mutable - Properties can be changed after creation
  • Stored by Reference - Variable holds reference to memory location
  • Have Methods - Objects can have functions as properties
  • Dynamic Properties - Properties can be added/removed at runtime

Type Checking and Detection

JavaScript provides several ways to check data types, each with different use cases and limitations.

javascript
1// typeof operator - basic type checking
2console.log(typeof "hello");        // "string"
3console.log(typeof 42);             // "number"
4console.log(typeof true);           // "boolean"
5console.log(typeof undefined);      // "undefined"
6console.log(typeof null);           // "object" (historical bug)
7console.log(typeof Symbol('id'));   // "symbol"
8console.log(typeof 123n);           // "bigint"
9console.log(typeof {});             // "object"
10console.log(typeof []);             // "object"
11console.log(typeof function() {});  // "function"
12
13// instanceof - check object inheritance
14console.log([] instanceof Array);    // true
15console.log({} instanceof Object);   // true
16console.log(new Date() instanceof Date); // true
17
18// Array.isArray() - proper array detection
19console.log(Array.isArray([]));      // true
20console.log(Array.isArray({}));      // false
21
22// Object.prototype.toString - detailed type info
23console.log(Object.prototype.toString.call([]));     // [object Array]
24console.log(Object.prototype.toString.call({}));     // [object Object]
25console.log(Object.prototype.toString.call(null));   // [object Null]
26
27// Custom type checking function
28function getType(value) {
29    if (value === null) return 'null';
30    if (Array.isArray(value)) return 'array';
31    return typeof value;
32}
33
34console.log(getType([]));    // 'array'
35console.log(getType(null));  // 'null'
36console.log(getType(42));    // 'number'

Type Conversion and Coercion

JavaScript automatically converts types (coercion) in operations, but you can also explicitly convert between types.

javascript
1// Explicit type conversion
2// String conversion
3const num = 123;
4console.log(String(num));        // "123"
5console.log(num.toString());     // "123"
6console.log('' + num);           // "123"
7
8// Number conversion
9const str = "456";
10console.log(Number(str));        // 456
11console.log(parseInt(str));      // 456
12console.log(parseFloat("78.9")); // 78.9
13console.log(+str);               // 456
14
15// Boolean conversion
16console.log(Boolean(1));         // true
17console.log(Boolean(0));         // false
18console.log(Boolean("hello"));   // true
19console.log(Boolean(""));        // false
20console.log(!!"hello");          // true (double negation)
21
22// Implicit type coercion
23console.log("5" + 3);           // "53" (string concatenation)
24console.log("5" - 3);           // 2 (numeric subtraction)
25console.log("5" * "2");         // 10 (numeric multiplication)
26console.log("10" / "2");        // 5 (numeric division)
27
28// Truthy and Falsy values
29// Falsy: false, 0, "", null, undefined, NaN
30// Truthy: everything else
31
32console.log(Boolean(0));         // false
33console.log(Boolean("0"));       // true
34console.log(Boolean(""));        // false
35console.log(Boolean("false"));   // true
36console.log(Boolean(null));      // false
37console.log(Boolean(undefined)); // false
38console.log(Boolean(NaN));       // false
39console.log(Boolean([]));        // true
40console.log(Boolean({}));        // true
41
42// Loose vs Strict equality
43console.log("5" == 5);          // true (loose, with coercion)
44console.log("5" === 5);         // false (strict, no coercion)
45console.log(null == undefined);  // true
46console.log(null === undefined); // false

Special Cases and Edge Cases

Understanding JavaScript's special type behaviors helps avoid common pitfalls and bugs.

javascript
1// NaN (Not a Number)
2console.log(typeof NaN);                    // "number"
3console.log(NaN === NaN);                   // false
4console.log(isNaN(NaN));                    // true
5console.log(isNaN("hello"));                // true
6console.log(Number.isNaN(NaN));             // true
7console.log(Number.isNaN("hello"));         // false
8
9// null vs undefined
10let testVar;
11console.log(testVar);                       // undefined
12console.log(typeof testVar);                // "undefined"
13console.log(typeof null);                   // "object" (historical JavaScript bug)
14
15// Empty values
16console.log(Boolean(""));                   // false
17console.log(Boolean(0));                    // false
18console.log(Boolean(null));                 // false
19console.log(Boolean(undefined));            // false
20
21// Array type quirks
22console.log(typeof []);                     // "object"
23console.log(Array.isArray([]));             // true
24console.log([] instanceof Array);           // true
25console.log([] instanceof Object);          // true
26
27// Function type
28console.log(typeof function() {});          // "function"
29console.log(function() {} instanceof Object); // true
30
31// Date type
32console.log(typeof new Date());             // "object"
33console.log(new Date() instanceof Date);    // true
34
35// Symbol uniqueness
36const sym1 = Symbol('test');
37const sym2 = Symbol('test');
38console.log(sym1 === sym2);                 // false
39
40// BigInt operations
41const big1 = 9007199254740991n;
42const big2 = 1n;
43console.log(big1 + big2);                   // 9007199254740992n
44// console.log(big1 + 1);                   // Error: cannot mix BigInt and number

Best Practices with Data Types

Following best practices for data types leads to more predictable and maintainable JavaScript code.

javascript
1// Use const for values that don't change
2const PI = 3.14159;
3const API_URL = "https://api.example.com";
4const CONFIG = {
5    timeout: 5000,
6    retries: 3
7};
8
9// Use meaningful variable names
10const userName = "John";           // GOOD
11const u = "John";                  // BAD
12const itemCount = 5;               // GOOD
13const ic = 5;                      // BAD
14
15// Use strict equality (===) instead of loose (==)
16const age = "25";
17if (age === 25) {                   // false - correct
18    console.log("Age is 25");
19}
20
21if (age == 25) {                    // true - might be unexpected
22    console.log("Age is 25");
23}
24
25// Check for null and undefined explicitly
26function processUser(user) {
27    if (user == null) {             // catches both null and undefined
28        return "No user provided";
29    }
30    return `Hello, ${user.name}`;
31}
32
33// Use Array.isArray() for array checking
34const items = [1, 2, 3];
35if (Array.isArray(items)) {         // GOOD
36    console.log("It's an array");
37}
38
39if (typeof items === "object") {    // BAD - also true for objects
40    console.log("Might be array or object");
41}
42
43// Use template literals for string concatenation
44const firstName = "John";
45const lastName = "Doe";
46const fullName = `${firstName} ${lastName}`;  // GOOD
47// const fullName = firstName + " " + lastName; // OK but less readable
48
49// Convert types explicitly when needed
50const userInput = "123";
51const numericValue = Number(userInput);      // EXPLICIT
52// const numericValue = +userInput;           // IMPLICIT - less clear

JavaScript Data Types FAQ

What's the difference between primitive and reference types?

Primitives are stored by value directly in memory, are immutable, and compared by value. Reference types are stored by reference, are mutable, and compared by reference.

Why does typeof null return 'object'?

This is a historical bug in JavaScript that can't be fixed due to backward compatibility. Use === null to properly check for null values.

How can I properly check if a value is an array?

Use Array.isArray(value) method, which returns true for arrays and false for other types including array-like objects.

What are truthy and falsy values?

Falsy values: false, 0, "", null, undefined, NaN. All other values are truthy and will evaluate to true in boolean contexts.

When should I use == vs === ?

Always use === (strict equality) unless you specifically need type coercion. === checks both value and type, while == performs type coercion before comparison.

What's the difference between null and undefined?

undefined means a variable has been declared but not assigned a value. null is an assignment value that represents intentional absence of any object value.

How do I convert a string to a number?

Use Number(), parseInt(), parseFloat(), or the unary + operator. Number() and + convert the entire string, while parseInt/parseFloat parse until invalid characters.

What is type coercion in JavaScript?

Type coercion is JavaScript's automatic conversion of values from one type to another when performing operations, like converting string to number in mathematical operations.

How are objects different from primitives?

Objects are mutable, stored by reference, can have methods and properties, support inheritance, while primitives are immutable, stored by value, and have no methods of their own.

What is NaN and how do I check for it?

NaN means 'Not a Number' and results from invalid mathematical operations. Use Number.isNaN() or isNaN() to check, but note isNaN() does type coercion while Number.isNaN() doesn't.