JavaScript
02 / 07

Modern JavaScript Patterns

Modern JavaScript Patterns

Array Methods

const numbers = [1, 2, 3, 4, 5];

// map - transform each element
const doubled = numbers.map(n => n * 2);  // [2, 4, 6, 8, 10]

// filter - keep elements that pass test
const evens = numbers.filter(n => n % 2 === 0);  // [2, 4]

// reduce - accumulate values
const sum = numbers.reduce((acc, n) => acc + n, 0);  // 15

// find - first element that matches
const users = [
  { id: 1, name: 'John', active: true },
  { id: 2, name: 'Jane', active: false },
  { id: 3, name: 'Bob', active: true }
];

const firstActive = users.find(u => u.active);  // { id: 1, ... }

// findIndex - index of first match
const index = users.findIndex(u => u.name === 'Jane');  // 1

// some - check if any element passes test
const hasActive = users.some(u => u.active);  // true

// every - check if all elements pass test
const allActive = users.every(u => u.active);  // false

// forEach - iterate
users.forEach((user, index) => {
  console.log(`${index}: ${user.name}`);
});

// flatMap - map then flatten
const nested = [[1, 2], [3, 4], [5, 6]];
const flattened = nested.flatMap(arr => arr);  // [1,2,3,4,5,6]

// flat - flatten arrays
const deep = [1, [2, [3, [4, 5]]]];
console.log(deep.flat());     // [1, 2, [3, [4, 5]]]
console.log(deep.flat(2));    // [1, 2, 3, [4, 5]]
console.log(deep.flat(Infinity));  // [1, 2, 3, 4, 5]

Optional Chaining & Nullish Coalescing

// Optional chaining (?.) - ES2020
const user = {
  name: 'John',
  address: {
    city: 'NYC'
  }
};

// Old way
const city = user && user.address && user.address.city;

// ES2020 way
const city = user?.address?.city;  // 'NYC'
const country = user?.address?.country;  // undefined (no error)

// With arrays
const firstUser = users?.[0];

// With methods
user.greet?.();  // Only call if exists

// Nullish coalescing (??) - ES2020
const value1 = null ?? 'default';      // 'default'
const value2 = undefined ?? 'default'; // 'default'
const value3 = 0 ?? 'default';         // 0 (not null/undefined)
const value4 = '' ?? 'default';        // '' (not null/undefined)
const value5 = false ?? 'default';     // false (not null/undefined)

// Compare with ||
const v1 = 0 || 'default';      // 'default' (0 is falsy)
const v2 = 0 ?? 'default';      // 0 (0 is not null/undefined)

// Logical assignment operators
let obj = { a: 1 };

obj.a ||= 10;   // obj.a = obj.a || 10;
obj.b ??= 20;   // obj.b = obj.b ?? 20;
obj.c &&= 30;   // obj.c = obj.c && 30;

Map, Set, WeakMap, WeakSet

// Map - key-value pairs (any type as key)
const map = new Map();

map.set('name', 'John');
map.set(1, 'number key');
map.set({}, 'object key');

console.log(map.get('name'));  // 'John'
console.log(map.has('name'));  // true
console.log(map.size);         // 3

map.delete('name');
map.clear();

// Iterate
for (const [key, value] of map) {
  console.log(key, value);
}

// Set - unique values
const set = new Set();

set.add(1);
set.add(2);
set.add(2);  // Duplicate ignored

console.log(set.size);     // 2
console.log(set.has(1));   // true

set.delete(1);
set.clear();

// Convert array to set (remove duplicates)
const numbers = [1, 2, 2, 3, 3, 4];
const unique = [...new Set(numbers)];  // [1, 2, 3, 4]

// WeakMap - keys are objects, can be garbage collected
const weakMap = new WeakMap();
let obj = { id: 1 };

weakMap.set(obj, 'metadata');
console.log(weakMap.get(obj));  // 'metadata'

obj = null;  // Object can be garbage collected

// WeakSet - similar to Set but with object values only
const weakSet = new WeakSet();
const obj1 = { id: 1 };
const obj2 = { id: 2 };

weakSet.add(obj1);
weakSet.add(obj2);

console.log(weakSet.has(obj1));  // true

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free