Data Types in JavaScript
JavaScript has dynamic typing - variables can hold different types of values. Understanding data types is crucial for effective programming.
📚 Primitive Data Types
JavaScript has 7 primitive data types that are immutable and stored by value.
1. Number
// Integers and decimals
let age = 25;
let price = 19.99;
let negative = -10;
// Special numeric values
let infinity = Infinity;
let negInfinity = -Infinity;
let notANumber = NaN; // Not a Number
// Number operations
console.log(10 / 0); // Infinity
console.log(-10 / 0); // -Infinity
console.log('text' * 2); // NaN
console.log(0 / 0); // NaN
// Checking for NaN
console.log(isNaN(NaN)); // true
console.log(isNaN('hello')); // true
console.log(Number.isNaN(NaN)); // true (better)
console.log(Number.isNaN('hello')); // false
// Number methods
let num = 3.14159;
console.log(num.toFixed(2)); // '3.14'
console.log(num.toPrecision(3)); // '3.14'
console.log(parseInt('42')); // 42
console.log(parseFloat('3.14')); // 3.14
// BigInt for very large numbers
const huge = 9007199254740991n; // Note the 'n'
const bigInt = BigInt(9007199254740991);
console.log(huge + 1n); // 9007199254740992n
2. String
// Single or double quotes
let single = 'Hello';
let double = "World";
// Template literals (backticks)
let name = 'John';
let greeting = `Hello, ${name}!`; // 'Hello, John!'
// Multi-line strings
let multiline = `This is
a multi-line
string`;
// String methods
let text = 'JavaScript';
console.log(text.length); // 10
console.log(text.toUpperCase()); // 'JAVASCRIPT'
console.log(text.toLowerCase()); // 'javascript'
console.log(text.charAt(0)); // 'J'
console.log(text.indexOf('Script')); // 4
console.log(text.slice(0, 4)); // 'Java'
console.log(text.split('')); // ['J','a','v','a','S','c','r','i','p','t']
// String concatenation
let first = 'Hello';
let second = 'World';
console.log(first + ' ' + second); // 'Hello World'
console.log(`${first} ${second}`); // 'Hello World'
// Escape characters
let quote = "He said, \"Hello!\"";
let path = 'C:\\Users\\John';
let newline = 'Line 1\nLine 2';
let tab = 'Column1\tColumn2';
3. Boolean
// Only two values: true or false
let isActive = true;
let isComplete = false;
// Boolean from comparisons
let isGreater = 10 > 5; // true
let isEqual = 10 === 10; // true
let isLess = 5 < 3; // false
// Logical operations
let and = true && false; // false
let or = true || false; // true
let not = !true; // false
// Truthy and falsy values
// Falsy: false, 0, '', null, undefined, NaN
// Everything else is truthy
console.log(Boolean(0)); // false
console.log(Boolean('')); // false
console.log(Boolean(null)); // false
console.log(Boolean(undefined)); // false
console.log(Boolean(NaN)); // false
console.log(Boolean(1)); // true
console.log(Boolean('hello')); // true
console.log(Boolean([])); // true
console.log(Boolean({})); // true
4. Undefined
// Variable declared but not assigned
let x;
console.log(x); // undefined
// Function with no return
function test() {
// no return statement
}
console.log(test()); // undefined
// Missing object property
let person = { name: 'John' };
console.log(person.age); // undefined
// Missing array element
let arr = [1, 2, 3];
console.log(arr[10]); // undefined
5. Null
// Intentional absence of value
let result = null;
// Difference between null and undefined
let notAssigned; // undefined
let intentionallyEmpty = null; // null
console.log(notAssigned); // undefined
console.log(intentionallyEmpty); // null
// Type checking quirk
console.log(typeof undefined); // 'undefined'
console.log(typeof null); // 'object' (historical bug!)
// Checking for null
console.log(result === null); // true
console.log(result == null); // true
console.log(result == undefined); // true (loose equality)
6. Symbol (ES6)
// Unique identifiers
let sym1 = Symbol('description');
let sym2 = Symbol('description');
console.log(sym1 === sym2); // false (always unique)
// Use in objects for unique keys
let id = Symbol('id');
let user = {
name: 'John',
[id]: 123 // Symbol as property key
};
console.log(user[id]); // 123
console.log(user.id); // undefined
// Symbols are not enumerable
for (let key in user) {
console.log(key); // Only 'name' (not Symbol)
}
// Global symbol registry
let globalSym1 = Symbol.for('app.id');
let globalSym2 = Symbol.for('app.id');
console.log(globalSym1 === globalSym2); // true
7. BigInt (ES2020)
// For integers larger than 2^53 - 1
const big = 9007199254740991n;
const alsoHuge = BigInt(9007199254740991);
console.log(big + 1n); // 9007199254740992n
// Cannot mix with regular numbers
// console.log(big + 1); // Error!
console.log(big + BigInt(1)); // Works
// Comparison works
console.log(1n < 2); // true
console.log(2n > 1); // true
console.log(2n === 2); // false (different types)
console.log(2n == 2); // true (loose equality)
🎯 Reference Types (Objects)
Object
// Object literal
let person = {
name: 'John',
age: 30,
city: 'New York',
greet: function() {
console.log(`Hi, I'm ${this.name}`);
}
};
// Accessing properties
console.log(person.name); // 'John' (dot notation)
console.log(person['age']); // 30 (bracket notation)
// Adding properties
person.country = 'USA';
person['email'] = 'john@example.com';
// Deleting properties
delete person.city;
// Nested objects
let user = {
name: 'Jane',
address: {
street: '123 Main St',
city: 'Boston',
zip: '02101'
}
};
console.log(user.address.city); // 'Boston'
Array
// Array literal
let numbers = [1, 2, 3, 4, 5];
let mixed = [1, 'hello', true, null, { name: 'John' }];
// Accessing elements
console.log(numbers[0]); // 1 (zero-indexed)
console.log(numbers[4]); // 5
// Array properties and methods
console.log(numbers.length); // 5
numbers.push(6); // Add to end
numbers.pop(); // Remove from end
numbers.unshift(0); // Add to start
numbers.shift(); // Remove from start
// Array methods
let doubled = numbers.map(n => n * 2);
let evens = numbers.filter(n => n % 2 === 0);
let sum = numbers.reduce((acc, n) => acc + n, 0);
// Multi-dimensional arrays
let matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
console.log(matrix[1][1]); // 5
Function
// Function declaration
function add(a, b) {
return a + b;
}
// Function expression
const subtract = function(a, b) {
return a - b;
};
// Arrow function
const multiply = (a, b) => a * b;
// Functions are objects
console.log(typeof add); // 'function'
add.customProperty = 'I am a property';
console.log(add.customProperty); // 'I am a property'
Date
// Creating dates
let now = new Date();
let specific = new Date('2025-01-01');
let timestamp = new Date(1640995200000);
// Date methods
console.log(now.getFullYear()); // 2025
console.log(now.getMonth()); // 0-11 (0 = January)
console.log(now.getDate()); // 1-31
console.log(now.getDay()); // 0-6 (0 = Sunday)
console.log(now.getHours()); // 0-23
console.log(now.getMinutes()); // 0-59
console.log(now.getSeconds()); // 0-59
// Formatting
console.log(now.toDateString()); // 'Wed Jan 01 2025'
console.log(now.toTimeString()); // '12:00:00 GMT+0000'
console.log(now.toISOString()); // '2025-01-01T12:00:00.000Z'
🔄 Type Checking
// 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' (bug!)
console.log(typeof Symbol('id')); // 'symbol'
console.log(typeof 123n); // 'bigint'
console.log(typeof {}); // 'object'
console.log(typeof []); // 'object' (arrays are objects)
console.log(typeof function() {}); // 'function'
// Better type checking
console.log(Array.isArray([])); // true
console.log(Array.isArray({})); // false
console.log(null === null); // true
console.log(value === undefined); // Check for undefined
// instanceof for objects
let date = new Date();
console.log(date instanceof Date); // true
console.log([] instanceof Array); // true
console.log({} instanceof Object); // true
// Object.prototype.toString for accurate type
function getType(value) {
return Object.prototype.toString.call(value).slice(8, -1);
}
console.log(getType([])); // 'Array'
console.log(getType({})); // 'Object'
console.log(getType(null)); // 'Null'
console.log(getType(new Date())); // 'Date'
🔁 Type Conversion
To String
// Explicit conversion
String(123); // '123'
String(true); // 'true'
String(null); // 'null'
String(undefined); // 'undefined'
String([1, 2, 3]); // '1,2,3'
String({ a: 1 }); // '[object Object]'
// Using toString()
let num = 42;
num.toString(); // '42'
true.toString(); // 'true'
// Template literals
`${123}`; // '123'
`${true}`; // 'true'
// Implicit conversion
123 + ''; // '123'
true + ''; // 'true'
To Number
// Explicit conversion
Number('123'); // 123
Number('12.34'); // 12.34
Number(''); // 0
Number(' '); // 0
Number('hello'); // NaN
Number(true); // 1
Number(false); // 0
Number(null); // 0
Number(undefined); // NaN
// Using parseInt and parseFloat
parseInt('123'); // 123
parseInt('123.45'); // 123
parseInt('123px'); // 123
parseFloat('123.45'); // 123.45
parseFloat('123.45px'); // 123.45
// Unary plus operator
+'123'; // 123
+'12.34'; // 12.34
+true; // 1
+false; // 0
// Implicit conversion
'5' * 2; // 10
'10' / 2; // 5
'10' - 5; // 5
'5' + 2; // '52' (concatenation!)
To Boolean
// Explicit conversion
Boolean(1); // true
Boolean(0); // false
Boolean('hello'); // true
Boolean(''); // false
Boolean(null); // false
Boolean(undefined); // false
Boolean(NaN); // false
Boolean({}); // true
Boolean([]); // true
// Double NOT operator
!!1; // true
!!0; // false
!!'hello'; // true
!!''; // false
// Implicit in conditionals
if ('hello') { // true
console.log('truthy');
}
if (0) { // false
console.log('won\'t run');
}
⚖️ Equality Comparisons
// Strict equality (===) - No type conversion
console.log(5 === 5); // true
console.log(5 === '5'); // false (different types)
console.log(true === 1); // false
console.log(null === undefined); // false
// Loose equality (==) - With type conversion
console.log(5 == '5'); // true (converts '5' to 5)
console.log(true == 1); // true (converts true to 1)
console.log(null == undefined); // true
console.log(0 == false); // true
console.log('' == false); // true
// Best practice: Use === (strict equality)
// Only use == when specifically checking for null/undefined
if (value == null) { // Checks for both null and undefined
console.log('value is null or undefined');
}
// Equivalent to:
if (value === null || value === undefined) {
console.log('value is null or undefined');
}
// Object equality
let obj1 = { name: 'John' };
let obj2 = { name: 'John' };
let obj3 = obj1;
console.log(obj1 === obj2); // false (different objects)
console.log(obj1 === obj3); // true (same reference)
💡 Practical Examples
Input Validation
function validateAge(age) {
// Convert to number
age = Number(age);
// Check if valid number
if (isNaN(age)) {
return 'Invalid age: not a number';
}
// Check range
if (age < 0 || age > 150) {
return 'Invalid age: out of range';
}
return 'Valid age';
}
console.log(validateAge(25)); // 'Valid age'
console.log(validateAge('25')); // 'Valid age'
console.log(validateAge('abc')); // 'Invalid age: not a number'
console.log(validateAge(-5)); // 'Invalid age: out of range'
Type-Safe Operations
function safeAdd(a, b) {
// Ensure both are numbers
a = Number(a);
b = Number(b);
if (isNaN(a) || isNaN(b)) {
throw new Error('Both arguments must be numbers');
}
return a + b;
}
console.log(safeAdd(5, 10)); // 15
console.log(safeAdd('5', '10')); // 15
// console.log(safeAdd('a', 'b')); // Error!
Default Values
function greet(name) {
// Using || for default value
name = name || 'Guest';
return `Hello, ${name}!`;
}
// Better: Using ?? (nullish coalescing - ES2020)
function greet2(name) {
name = name ?? 'Guest'; // Only null/undefined, not falsy
return `Hello, ${name}!`;
}
console.log(greet()); // 'Hello, Guest!'
console.log(greet('John')); // 'Hello, John!'
console.log(greet('')); // 'Hello, Guest!' (empty string is falsy)
console.log(greet2('')); // 'Hello, !' (keeps empty string)
console.log(greet2(null)); // 'Hello, Guest!'
🎯 Key Takeaways
- 7 Primitives: number, string, boolean, undefined, null, symbol, bigint
- Dynamic typing: Variables can hold any type of value
- typeof: Returns the type of a value (with some quirks like null)
- Type conversion: Explicit with Number(), String(), Boolean() or implicit
- === vs ==: Always use strict equality (===) unless checking null/undefined
- Falsy values: false, 0, '', null, undefined, NaN - everything else is truthy
- Objects: Arrays, functions, dates are all objects (reference types)
- NaN: Result of invalid math operations, use Number.isNaN() to check