Implementing a Javascript hashmap

January 03, 2026 by Andrew Smith

When building performant JavaScript applications, data structures play a crucial role in optimizing both speed and resource usage. One such powerful data structure is the hashmap—a collection that allows storing key-value pairs with quick retrieval. While JavaScript provides a native Map and Object, implementing your own hashmap increases your understanding of how hashes work under the hood and how you might customize one for specific use cases.

TL;DR

A hashmap is a data structure that stores data in key-value pairs, allowing fast retrieval. While JavaScript has built-in options like Map and Object, implementing one manually reinforces understanding of hashing, collision handling, and performance considerations. This article walks through building a simple hashmap from scratch, explores key features, and discusses custom optimizations. It’s a beginner-friendly guide to data structure mastery in JavaScript.

What is a Hashmap?

A hashmap (also called a hash table) is a data structure that maps keys to values for highly efficient lookup. It uses a hash function to convert a key into an index in an underlying array. This enables:

  • Constant-time (O(1)) average-case lookups
  • Efficient insert, update, and delete operations
  • Support for custom key types (in native Map)

In a typical scenario, you want to store and retrieve information quickly without scanning an entire list or array. For example, counting word frequency in a sentence or storing configuration options for an app’s state can become much faster when utilizing a hashmap.

Why Build Your Own Hashmap?

JavaScript’s Map class and plain objects provide hashing functionality, but writing your own hashmap gives insight into the inner workings of data structures like collision handling, hashing algorithms, and scalability issues.

Here’s what you learn by implementing a hashmap:

  • Understanding of hashing mechanics
  • Techniques to handle hash collisions (like chaining or open addressing)
  • How to resize or rehash when the table grows
  • The trade-off between memory and performance

Let’s dive into the core components of building a hashmap from scratch using JavaScript.

Core Concepts of a Hashmap

Hash Function

A hash function converts a string key into a deterministic index for storing the value. JavaScript does not expose native hash functions like some lower-level languages, but for our purposes, a simple function works fine.


function hashStringToIndex(key, arrayLength) {
  let hash = 0;
  for (let char of key) {
    hash = (hash + char.charCodeAt(0) * 17) % arrayLength;
  }
  return hash;
}

This function ensures the same key will always produce the same index (modulo array size), though it’s a basic version. For example:

hashStringToIndex("apple", 100) // Might return 37

Handling Collisions

When two keys hash to the same index, we get a collision. We cannot overwrite existing values, so we need to handle that gracefully. One of the simplest methods is separate chaining—using arrays within each bucket.

Think of your underlying storage as an array of buckets. Each bucket holds an array of key-value pairs that hash to the same index.

Building the Hashmap Class

Now let’s implement a simplified hashmap class in JavaScript:


class HashMap {
  constructor(size = 53) {
    this.keyMap = new Array(size);
  }

  _hash(key) {
    let total = 0;
    for (let char of key) {
      total = (total + char.charCodeAt(0) * 13) % this.keyMap.length;
    }
    return total;
  }

  set(key, value) {
    const index = this._hash(key);
    if (!this.keyMap[index]) {
      this.keyMap[index] = [];
    }
    for (let i = 0; i < this.keyMap[index].length; i++) {
      if (this.keyMap[index][i][0] === key) {
        this.keyMap[index][i][1] = value;
        return;
      }
    }
    this.keyMap[index].push([key, value]);
  }

  get(key) {
    const index = this._hash(key);
    const bucket = this.keyMap[index];
    if (bucket) {
      for (let pair of bucket) {
        if (pair[0] === key) {
          return pair[1];
        }
      }
    }
    return undefined;
  }

  keys() {
    const keysArray = [];
    for (let bucket of this.keyMap) {
      if (bucket) {
        for (let pair of bucket) {
          keysArray.push(pair[0]);
        }
      }
    }
    return keysArray;
  }

  values() {
    const valuesArray = [];
    for (let bucket of this.keyMap) {
      if (bucket) {
        for (let pair of bucket) {
          valuesArray.push(pair[1]);
        }
      }
    }
    return valuesArray;
  }
}

Using Your Hashmap


const myMap = new HashMap();

myMap.set("name", "Alice");
myMap.set("age", 30);
myMap.set("occupation", "Engineer");

console.log(myMap.get("name")); // Alice
console.log(myMap.get("age"));  // 30
console.log(myMap.keys());      // ["name", "age", "occupation"]

Even though simplified, this structure supports key insertion, retrieval, and lookup of all keys or values.

Optimizing and Scaling

As you scale up your hashmap, you’ll run into more advanced topics like:

  • Resizing the internal array when load factor exceeds a threshold
  • Using better hash functions (FNV, DJB2)
  • Storing large datasets with less collision
  • Supporting additional operations like deletion

Customizations

You might want to:

  • Restrict key types (e.g., only strings or numbers)
  • Implement weak references for garbage-collected keys
  • Support deeper equality checks for complex keys

Although native Map does a lot of these already, learning to write these features yourself puts you in control of performance tuning and logic flow.

Hashmap vs Object vs Map

Here’s a brief comparison:

Feature Object Map Custom Hashmap
Key Types Strings or Symbols Any (inc. functions, objects) Depends on implementation
Order Preserved No specific guarantee Yes No (unless added)
Speed High for small sets High, optimized by engine Customizable & learning-oriented
Extensibility Low Medium High (write your own logic)

Conclusion

Implementing a hashmap in JavaScript from scratch is an enlightening journey that clarifies both the theoretical and practical workings of an essential data structure. You gain insight into hashing, memory management, collision handling, and lookup algorithms—all fundamental skills for advanced development or technical interviews.

While JavaScript offers built-in tools like Map and Object for most real-world use cases, knowing how these underpinnings work gives you a priceless advantage when performance optimization or custom logic is required.

So next time you reach for a native map, you’ll know exactly what’s happening beneath the hood—and how to tune it for your specific needs.