Data Types in Depth
Now that you know the basics, letβs explore JavaScriptβs data types in detail.
Methods of Primitives
Primitives (string, number, boolean, etc.) are not objects. But you can call methods on them:
let str = "hello";
console.log(str.toUpperCase()); // β "HELLO"
How does this work? JavaScript creates a temporary wrapper object:
- A special βobject wrapperβ is created
- The method runs
- The wrapper is destroyed
// Behind the scenes:
let str = "hello";
// JS temporarily creates new String("hello")
// Calls .toUpperCase()
// Destroys the wrapper
// Primitives stay primitive β the wrapper is temporary
str.test = 5; // Wrapper created, property set, wrapper destroyed
console.log(str.test); // β undefined (new wrapper has no test)
Primitive Wrappers
| Primitive | Wrapper | Example |
|---|---|---|
string | String | "hello".length |
number | Number | (3.14).toFixed(1) |
boolean | Boolean | true.toString() |
symbol | Symbol | Symbol("id").description |
bigint | BigInt | 100n.toString() |
// null and undefined have no wrapper methods
// null.toString(); // TypeError!
Numbers
Writing Numbers
let billion = 1000000000;
let billion2 = 1_000_000_000; // Underscores as separators (ES2021)
let billion3 = 1e9; // Scientific notation
let micro = 1e-6; // 0.000001
let hex = 0xFF; // 255 (hexadecimal)
let oct = 0o77; // 63 (octal)
let bin = 0b1010; // 10 (binary)
Number Methods
let num = 3.14159;
// Round to n decimal places
num.toFixed(2); // β "3.14" (returns string!)
num.toFixed(0); // β "3"
// Convert to string in different base
num.toString(16); // β "3.243f..." (hex)
// Parse from string
parseInt("100px"); // β 100
parseFloat("3.14em"); // β 3.14
parseInt("0xFF", 16); // β 255 (explicit base)
// Check if finite
isFinite(Infinity); // β false
isFinite(42); // β true
isFinite("42"); // β true (converts)
// Check if NaN (only reliable way)
Number.isNaN(NaN); // β true
Number.isNaN("abc"); // β false (doesn't convert)
isNaN("abc"); // β true (converts first)
Imprecise Calculations
console.log(0.1 + 0.2); // β 0.30000000000000004 (not 0.3!)
console.log(0.1 + 0.2 === 0.3); // β false
This happens because numbers are stored in binary (base-2) and some decimal fractions canβt be represented exactly.
Fix: Round to a certain precision:
let sum = 0.1 + 0.2;
console.log(+sum.toFixed(2)); // β 0.3
Safe Integer Range
Number.MAX_SAFE_INTEGER; // β 9007199254740991
Number.MIN_SAFE_INTEGER; // β -9007199254740991
// Beyond this range, integer math is unreliable
console.log(9007199254740991+1); // β 9007199254740992 (wrong!)
console.log(9007199254740991+2); // β 9007199254740992 (same result!)
For larger integers, use BigInt.
Demo: Numbers Demo
JavaScript
document.write('PI to 2 decimals: ' + (Math.PI.toFixed(2)) + '<br>');
document.write('Parse \'100px\': ' + parseInt('100px') + '<br>');
document.write('Parse \'3.14em\': ' + parseFloat('3.14em') + '<br>');
document.write('Hex 0xFF: ' + 0xFF + '<br>');
document.write('Binary 0b1010: ' + 0b1010 + '<br>');
document.write('0.1 + 0.2 = ' + (0.1 + 0.2) + '<br>');
document.write('Fixed: ' + +(0.1 + 0.2).toFixed(2) + '<br>');
document.write('Random 1-10: ' + Math.floor(Math.random() * 10 + 1) + '<br>'); Live Output Window
Strings
Creating Strings
let single = 'Hello';
let double = "Hello";
let template = `Hello ${name}!`; // Template literal (ES6)
Escape Sequences
let str = "Line 1\nLine 2"; // Newline
let str2 = "Tab\there"; // Tab
let str3 = "Back\\slash"; // Backslash
let str4 = "Quote: \""; // Double quote
String Length
"hello".length; // β 5
"".length; // β 0
"hello\n".length; // β 6 (newline counts as one character)
Accessing Characters
let str = "hello";
str[0]; // β "h"
str[1]; // β "e"
str.at(-1); // β "o" (ES2022 β negative indexing!)
str.at(-2); // β "l"
str.charAt(0); // β "h"
Changing Case
"Hello".toUpperCase(); // β "HELLO"
"Hello".toLowerCase(); // β "hello"
Searching
let str = "Hello World";
str.indexOf("World"); // β 6
str.indexOf("o"); // β 4 (first occurrence)
str.indexOf("o", 5); // β 7 (search from position 5)
str.indexOf("xyz"); // β -1 (not found)
str.includes("World"); // β true
str.startsWith("He"); // β true
str.endsWith("ld"); // β true
Substrings
let str = "JavaScript";
str.slice(0, 4); // β "Java" (start, end β end exclusive)
str.slice(4); // β "Script" (from index 4 to end)
str.slice(-6); // β "Script" (negative = from end)
str.substring(0, 4); // β "Java" (same as slice)
str.substring(4, 0); // β "Java" (swaps if start > end)
str.substr(4, 3); // β "Scr" (start, length β legacy, avoid)
Splitting and Joining
"a,b,c".split(","); // β ["a", "b", "c"]
"hello".split(""); // β ["h", "e", "l", "l", "o"]
["a", "b", "c"].join(","); // β "a,b,c"
["a", "b", "c"].join(""); // β "abc"
Trimming
" hello ".trim(); // β "hello"
" hello ".trimStart(); // β "hello "
" hello ".trimEnd(); // β " hello"
Padding
"5".padStart(3, "0"); // β "005"
"5".padEnd(3, "0"); // β "500"
"abc".padStart(5); // β " abc" (default pad with spaces)
Replace
"Hello World".replace("World", "JS"); // β "Hello JS" (first only)
"Hello World".replace(/o/g, "0"); // β "Hell0 W0rld" (global regex)
"Hello World".replaceAll("o", "0"); // β "Hell0 W0rld" (ES2021 β all)
Template Literals
let name = "Alice";
let age = 30;
// Multi-line strings
let html = `
<div>
<h1>${name}</h1>
<p>Age: ${age}</p>
</div>
`;
// Expressions inside ${}
let total = `Sum: ${2 + 3}`; // β "Sum: 5"
// Tagged templates (advanced)
function highlight(strings, ...values) {
return strings.reduce((result, str, i) => {
return result + str + (values[i] ? `<mark>${values[i]}</mark>` : "");
}, "");
}
let result = highlight`Hello ${name}, you are ${age} years old`;
Demo: Strings Demo
JavaScript
let str = 'JavaScript is awesome!';
document.write('String: ' + str + '<br>');
document.write('Length: ' + str.length + '<br>');
document.write('First char: ' + str[0] + '<br>');
document.write('Last char: ' + str.at(-1) + '<br>');
document.write('Uppercase: ' + str.toUpperCase() + '<br>');
document.write('Includes awesome': ' + str.includes('awesome') + '<br>');
document.write('Slice(0,10): ' + str.slice(0, 10) + '<br>');
document.write('Replace: ' + str.replace('awesome', 'great') + '<br>'); Live Output Window
Arrays
Arrays store ordered collections:
let fruits = ["Apple", "Banana", "Orange"];
let mixed = [1, "hello", true, null, { name: "Alice" }];
let empty = [];
Array Access
let fruits = ["Apple", "Banana", "Orange"];
fruits[0]; // β "Apple"
fruits[1]; // β "Banana"
fruits.at(-1); // β "Orange" (ES2022)
fruits.length; // β 3
Array length is writable
let arr = [1, 2, 3, 4, 5];
arr.length = 3;
console.log(arr); // β [1, 2, 3] (truncated!)
arr.length = 0; // Clear the array
Adding / Removing Elements
let fruits = ["Apple"];
// Push / Pop β end of array
fruits.push("Banana"); // β ["Apple", "Banana"] (add to end)
fruits.pop(); // β "Banana", fruits is ["Apple"] (remove from end)
// Shift / Unshift β beginning of array
fruits.unshift("Orange"); // β ["Orange", "Apple"] (add to start)
fruits.shift(); // β "Orange", fruits is ["Apple"] (remove from start)
// Splice β general purpose
let arr = [1, 2, 3, 4, 5];
arr.splice(1, 2); // β [2, 3] (removed), arr is [1, 4, 5]
arr.splice(1, 0, 2, 3); // Insert at index 1: arr is [1, 2, 3, 4, 5]
arr.splice(2, 1, 99); // Replace at index 2: arr is [1, 2, 99, 4, 5]
Iterating Arrays
let arr = [10, 20, 30];
// for loop
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
// for...of (access values)
for (let value of arr) {
console.log(value);
}
// forEach (functional)
arr.forEach((value, index) => {
console.log(`${index}: ${value}`);
});
Array.isArray
Array.isArray([1, 2, 3]); // β true
Array.isArray({}); // β false
Array.isArray("hello"); // β false
typeof []; // β "object" (arrays are objects!)
Array Methods
Transformative Methods
let arr = [1, 2, 3, 4, 5];
// map β transform each element
let doubled = arr.map(n => n * 2); // β [2, 4, 6, 8, 10]
// filter β keep elements that pass a test
let evens = arr.filter(n => n % 2 === 0); // β [2, 4]
// reduce β accumulate to a single value
let sum = arr.reduce((acc, n) => acc + n, 0); // β 15
// reduceRight β same but right to left
Searching Methods
let arr = [1, 2, 3, 4, 5, 3];
arr.indexOf(3); // β 2 (first occurrence)
arr.lastIndexOf(3); // β 5 (last occurrence)
arr.includes(3); // β true
// find β returns the first element that passes
arr.find(n => n > 3); // β 4
// findIndex β returns the index
arr.findIndex(n => n > 3); // β 3
// findLast (ES2023)
arr.findLast(n => n > 3); // β 5
// some β tests if any element passes
arr.some(n => n > 4); // β true
// every β tests if ALL elements pass
arr.every(n => n > 0); // β true
Sorting
let arr = [3, 1, 4, 1, 5, 9, 2, 6];
arr.sort(); // β [1, 1, 2, 3, 4, 5, 6, 9]
// But sort converts to strings first!
[10, 2, 1].sort(); // β [1, 10, 2] (lexicographic!)
// Fix β provide a comparator
arr.sort((a, b) => a - b); // Ascending: β [1, 2, 3, 4, 5, 6, 9]
arr.sort((a, b) => b - a); // Descending
// reverse
arr.reverse(); // Reverses the array in place
Other Useful Methods
let arr = [1, 2, 3];
// concat
arr.concat([4, 5]); // β [1, 2, 3, 4, 5]
// slice (extract portion, no mutation)
arr.slice(0, 2); // β [1, 2]
arr.slice(-2); // β [2, 3]
// flat (ES2019) β flatten nested arrays
[1, [2, [3]]].flat(); // β [1, 2, [3]] (default depth 1)
[1, [2, [3]]].flat(2); // β [1, 2, 3]
[1, [2, [3]]].flat(Infinity); // β [1, 2, 3] (all levels)
// flatMap β map then flat(1)
["hello world", "foo bar"].flatMap(s => s.split(" "));
// β ["hello", "world", "foo", "bar"]
// fill
[1, 2, 3].fill(0); // β [0, 0, 0]
Chaining
Array methods can be chained together:
let students = [
{ name: "Alice", score: 85 },
{ name: "Bob", score: 62 },
{ name: "Charlie", score: 92 },
{ name: "Diana", score: 47 }
];
let topStudents = students
.filter(s => s.score >= 70)
.map(s => s.name)
.sort();
console.log(topStudents); // β ["Alice", "Charlie"]
Demo: Array Methods Demo
JavaScript
let numbers = [5, 2, 8, 1, 9, 3];
document.write('Original: ' + numbers.join(', ') + '<br>');
let doubled = numbers.map(n => n * 2);
document.write('Doubled: ' + doubled.join(', ') + '<br>');
let evens = numbers.filter(n => n % 2 === 0);
document.write('Evens: ' + evens.join(', ') + '<br>');
let sorted = [...numbers].sort((a, b) => a - b);
document.write('Sorted: ' + sorted.join(', ') + '<br>');
let sum = numbers.reduce((acc, n) => acc + n, 0);
document.write('Sum: ' + sum + '<br>');
// Practical example
let words = ['hello', 'world', 'foo', 'bar'];
let upper = words.map(w => w.toUpperCase());
document.write('<br>Uppercased: ' + upper.join(', ') + '<br>');
let longWords = words.filter(w => w.length > 3);
document.write('Long words: ' + longWords.join(', ') + '<br>'); Live Output Window