Data Types Β· Astro Tech Blog

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:

  1. A special β€œobject wrapper” is created
  2. The method runs
  3. 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

PrimitiveWrapperExample
stringString"hello".length
numberNumber(3.14).toFixed(1)
booleanBooleantrue.toString()
symbolSymbolSymbol("id").description
bigintBigInt100n.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