Data Structures
Definition
Section titled “Definition”Data structure is a data organization and storage format that is usually chosen for efficient access to data.
Data structures are the shapes your data takes so your code stays readable, performant, and maintainable. In JavaScript, Arrays, Objects, Maps, and Sets cover most day-to-day needs, while WeakMaps and WeakSets handle object-linked metadata without memory leaks. Picking the right tool clarifies intent and reduces accidental complexity.
Introduction
Section titled “Introduction”As developers, we manipulate data constantly. Whether it’s state management in a component, processing API responses on the server, or optimizing database queries, the way we structure our data matters.
Choosing the appropriate data structure is about writing code that is:
- Readable: Intent is clear.
- Performant: Operations like search, insertion, and deletion are optimized.
- Maintainable: Easy to debug and extend.
In the TypeScript/JavaScript ecosystem, we have several built-in structures at our disposal.
JS Built-in Data Structures
Section titled “JS Built-in Data Structures”Arrays (Lists)
Section titled “Arrays (Lists)”Ordered collections of items.
Use case: Rendering a list of components.
// A simple todo listinterface Todo { id: number; text: string; done: boolean;}
const todos: Todo[] = [ { id: 1, text: 'Learn TypeScript', done: true }, { id: 2, text: 'Master Data Structures', done: false },];
// Iterating is cheap and easytodos.forEach(todo => console.log(todo.text));Objects (Dictionaries)
Section titled “Objects (Dictionaries)”Key-value pairs with string or symbol keys. Great for simple records and fast lookups, but keep key coercion and prototype properties in mind.
Use case: Storing user profiles, configuration settings, or indexing data by ID for O(1) access.
// Indexing users by ID for instant lookupconst usersById: Record<string, { name: string; role: string }> = { 'u-123': { name: 'Alice', role: 'admin' }, 'u-456': { name: 'Bob', role: 'editor' },};
// Instant access without loopingconst alice = usersById['u-123'];Collections of unique values.
Use case: Managing selected filters, tracking visited URLs, ensuring no duplicate tags.
// Managing selected tags in a filter componentconst selectedTags = new Set<string>();
selectedTags.add('react');selectedTags.add('typescript');selectedTags.add('react'); // Duplicate is ignored!
console.log(selectedTags.has('typescript')); // trueconsole.log(selectedTags.size); // 2Similar to Objects, but with some key differences: keys can be of any type (not
just strings/symbols), maintains insertion order (guaranteed since ES2015), and has a size property.
Use case: Caching API responses where keys might be complex objects or when frequent additions/removals occur.
// Simple in-memory cacheconst apiCache = new Map<string, Promise<Response>>();
function getCachedData(url: string): Promise<Response> { const cached = apiCache.get(url); if (cached) { return cached; } const data = fetch(url); // Assume this function fetches data apiCache.set(url, data); return data;}(Less Common / More Specific) JS Built-in Data Structures
Section titled “(Less Common / More Specific) JS Built-in Data Structures”WeakMaps
Section titled “WeakMaps”A WeakMap is like a Map, but with key differences: keys must be objects
(not primitives), and the references are “weak” — meaning if there are no other
references to the key object, it can be garbage collected.
Use case: Storing private data for objects, caching computed values without preventing garbage collection, or associating metadata with DOM nodes.
// Storing private data without memory leaksconst privateData = new WeakMap<object, { secret: string }>();
// Factory function to create usersconst createUser = (name: string, secret: string) => { const user = { name }; privateData.set(user, { secret }); return user;};
// Pure function to retrieve secretconst getSecret = (user: object) => privateData.get(user)?.secret;
// Usageconst alice = createUser('Alice', 'my-secret');console.log(getSecret(alice)); // 'my-secret'
// When alice is no longer referenced,// its entry in privateData is automatically cleaned upWeakSets
Section titled “WeakSets”A WeakSet is similar to a Set, but only holds objects (not primitives) and
the references are “weak” — objects can be garbage collected if there are no
other references to them. Unlike Set, you can’t iterate over a WeakSet or
get its size.
Use case: Tracking objects without preventing garbage collection, marking objects as processed, or managing object-based flags.
// Tracking which DOM nodes have been initializedconst initializedNodes = new WeakSet<HTMLElement>();
function initializeElement(element: HTMLElement) { if (initializedNodes.has(element)) { return; // Already initialized }
// ... perform initialization ... initializedNodes.add(element);}
// When the element is removed from DOM and no longer referenced,// it's automatically removed from the WeakSetConclusion
Section titled “Conclusion”Data structures are trade-offs. Arrays and Objects are the everyday tools, Maps and Sets add stronger semantics, and WeakMaps/WeakSets help you attach data without blocking garbage collection. The best choice is the one that makes intent obvious and operations efficient for your use case.
Resources
Section titled “Resources”- Wikipedia article on Data Structures
- MDN reference for Map
- MDN reference for Set
- MDN reference for WeakMap
- MDN reference for WeakSet
- Data Structures in JavaScript by freeCodeCamp
- MDN Documentation on Keyed Collections
Next: Dive deeper into Advanced Data Structures like Linked Lists, Trees, Graphs, and Tries.