Skip to main content

Command Palette

Search for a command to run...

String Polyfills and Common Interview Methods in JavaScript

Updated
5 min readView as Markdown

JavaScript provides us with a rich toolkit of built-in string methods. Need to find a word? Use .includes(). Need to duplicate text? Call .repeat(). In our day-to-day development, we treat these methods like magic black boxes: we put data in, and the correct result pops out.

But what happens when you sit down for a technical interview and the interviewer asks: "Can you write your own version of .includes() without using any built-in string search methods?"

Suddenly, the black box is open. To pass the test, you have to prove you understand exactly how the JavaScript engine parses and manipulates text. Let's explore why developers write polyfills, the logic behind common string utilities, and how to tackle these classic interview questions.

What is a Polyfill? (And Why Do Interviewers Love Them?)

A polyfill is a piece of code (usually JavaScript on the web) used to provide modern functionality on older browsers that do not natively support it. For example, if an ancient browser didn't know what String.prototype.includes was, developers would write a custom function and attach it to the String prototype so their modern code wouldn't crash.

Today, browsers update automatically, so we rarely write string polyfills for compatibility. However, interviewers love asking you to write polyfills because it tests three crucial skills:

  1. Algorithmic Thinking: Can you break a high-level task down into fundamental loops and conditions?

  2. Edge Case Awareness: Do you remember to handle negative numbers, empty strings, or invalid data types?

  3. Language Mechanics: Do you understand how the this keyword behaves when attached to a prototype?

Let's look at how to implement a few common string methods from scratch.

Deep Dive 1: Recreating String.prototype.repeat()

The .repeat(count) method takes a number and returns a new string containing the original text repeated that many times.

The Built-in Behavior:

"abc".repeat(3); // Returns: "abcabcabc"

The Problem-Solving Logic: To build this, we need to handle a few things:

  1. We need access to the string itself (using the this keyword).

  2. We need to loop count times, appending the string to a result variable.

  3. The Edge Cases: What if the count is negative? What if it is Infinity? The official JavaScript specification throws a RangeError in these cases, so our polyfill must do the same.

The Implementation:

String.prototype.myRepeat = function(count) {
  // Edge Case 1: Count cannot be negative
  if (count < 0) {
    throw new RangeError("Invalid count value");
  }

  // Edge Case 2: Count cannot be Infinity
  if (count === Infinity) {
    throw new RangeError("Invalid count value");
  }

  // Convert the count to an integer (in case a float was passed)
  count = Math.floor(count);

  let result = "";
  let stringToRepeat = this; // 'this' points to the string calling the method

  // Core Logic: Simply append the string to the result 'count' times
  for (let i = 0; i < count; i++) {
    result += stringToRepeat;
  }

  return result;
};

console.log("ha".myRepeat(3)); // Output: "hahaha"

Deep Dive 2: Recreating String.prototype.includes()

The .includes(searchString) method checks if a specific sequence of characters exists within the string, returning true or false.

The Built-in Behavior:

"hello world".includes("world"); // Returns: true

The Problem-Solving Logic: How do we find a needle in a haystack without using .indexOf() or .search()? We have to use a "sliding window" approach.

  1. We loop through the main string one character at a time.

  2. At each character, we check: Does this character, and the ones immediately following it, match our target word?

  3. If we find a complete match, return true. If we finish the loop without a match, return false.

The Implementation:

String.prototype.myIncludes = function(searchString) {
  const target = String(searchString); // Ensure it's a string
  const mainString = this;

  // If the target is longer than the string, it can't possibly fit
  if (target.length > mainString.length) return false;

  // Loop through the main string
  // We stop early (mainString.length - target.length) because there isn't 
  // enough room left for the target string to fit at the end.
  for (let i = 0; i <= mainString.length - target.length; i++) {
    let match = true;

    // Check the next characters against the target string
    for (let j = 0; j < target.length; j++) {
      if (mainString[i + j] !== target[j]) {
        match = false; // The moment a character doesn't match, break the inner loop
        break;
      }
    }

    // If the inner loop finished and match is still true, we found it!
    if (match) return true;
  }

  return false; // Target was not found
};

console.log("javascript".myIncludes("script")); // Output: true
console.log("javascript".myIncludes("python")); // Output: false

The Importance of Understanding Built-in Behavior

When preparing for interviews, it is easy to focus only on solving complex LeetCode algorithms. However, a deep understanding of JavaScript's native string utilities demonstrates a maturity in your engineering skills.

By practicing polyfills, you aren't just memorizing trivia. You are learning how to handle pointer management in loops, how to safely attach methods to prototypes, and how to rigorously validate inputs—all of which are critical skills for writing robust, production-level code.

The next time you use a built-in array or string method, take a moment to ask yourself: "Could I build this from scratch?" If the answer is yes, you are ready for the interview.