JavaScript Patterns & Collections
Array Methods
Essential functional array methods
const hosts = [
{ name: "sw01", vlan: 10, active: true },
{ name: "sw02", vlan: 20, active: false },
{ name: "fw01", vlan: 10, active: true },
{ name: "sw03", vlan: 20, active: true },
];
// map — transform each element
const names = hosts.map(h => h.name);
// ["sw01", "sw02", "fw01", "sw03"]
// filter — keep matching elements
const active = hosts.filter(h => h.active);
// find — first match
const firewall = hosts.find(h => h.name.startsWith("fw"));
// some / every
const hasInactive = hosts.some(h => !h.active); // true
const allActive = hosts.every(h => h.active); // false
// reduce — accumulate
const byVlan = hosts.reduce((acc, h) => {
(acc[h.vlan] ??= []).push(h);
return acc;
}, {});
// { 10: [{sw01}, {fw01}], 20: [{sw02}, {sw03}] }
// flatMap — map + flatten
const ports = hosts.flatMap(h => h.ports ?? []);
// sort (mutates!) — use toSorted() to avoid mutation
const sorted = [...hosts].sort((a, b) => a.name.localeCompare(b.name));
Object Methods
Keys, values, entries, fromEntries
const config = { host: "localhost", port: 8080, debug: true };
Object.keys(config); // ["host", "port", "debug"]
Object.values(config); // ["localhost", 8080, true]
Object.entries(config); // [["host","localhost"], ["port",8080], ["debug",true]]
// Transform object entries
const upper = Object.fromEntries(
Object.entries(config).map(([k, v]) => [k.toUpperCase(), v])
);
// { HOST: "localhost", PORT: 8080, DEBUG: true }
// Merge objects
const merged = { ...defaults, ...overrides };
const merged2 = Object.assign({}, defaults, overrides);
Map and Set
Modern collections
// Map — any key type, ordered, iterable
const cache = new Map();
cache.set("sw01", { ip: "10.50.1.10" });
cache.get("sw01"); // { ip: "10.50.1.10" }
cache.has("sw01"); // true
cache.delete("sw01");
cache.size; // 0
for (const [key, value] of cache) {
console.log(key, value);
}
// Set — unique values
const seen = new Set();
seen.add("10.50.1.1");
seen.add("10.50.1.1"); // no-op
seen.size; // 1
seen.has("10.50.1.1"); // true
// Deduplicate an array
const unique = [...new Set([1, 2, 2, 3, 3, 3])];
// [1, 2, 3]
Map preserves insertion order and accepts any key type (objects, functions). Plain objects coerce keys to strings.
Error Classes
Custom error types
class AppError extends Error {
constructor(message, statusCode) {
super(message);
this.name = "AppError";
this.statusCode = statusCode;
}
}
class NotFoundError extends AppError {
constructor(resource) {
super(`${resource} not found`, 404);
this.name = "NotFoundError";
}
}
try {
throw new NotFoundError("Host sw99");
} catch (err) {
if (err instanceof NotFoundError) {
console.log(err.statusCode); // 404
}
}
Generators
Lazy sequences with function*
function* range(start, end) {
for (let i = start; i < end; i++) {
yield i;
}
}
for (const n of range(0, 5)) {
console.log(n); // 0, 1, 2, 3, 4
}
// Infinite sequence
function* fibonacci() {
let [a, b] = [0, 1];
while (true) {
yield a;
[a, b] = [b, a + b];
}
}
// Take first 10
const first10 = [];
for (const n of fibonacci()) {
first10.push(n);
if (first10.length >= 10) break;
}
Generators are lazy — values are produced one at a time. Combined with for…of, they provide memory-efficient iteration over large or infinite sequences.
Proxy
Intercept object operations
const handler = {
get(target, prop) {
console.log(`accessing ${prop}`);
return prop in target ? target[prop] : `unknown: ${prop}`;
},
set(target, prop, value) {
if (prop === "port" && (value < 1 || value > 65535)) {
throw new RangeError(`Invalid port: ${value}`);
}
target[prop] = value;
return true;
},
};
const config = new Proxy({}, handler);
config.port = 8080; // OK
// config.port = 99999; // RangeError
Proxies intercept property access, assignment, deletion, and more. Use them for validation, logging, and reactive programming patterns.