Skip to main content

Command Palette

Search for a command to run...

String Polyfills and Common Interview Methods in JavaScript

Published
6 min read
String Polyfills and Common Interview Methods in JavaScript

What Even Are String Methods?

Before we talk about polyfills, let's make sure we're on the same page about what string methods actually are.

In JavaScript, a string isn't just a bunch of characters; it's an object under the hood.
And like any object, it comes with built-in methods you can call on it. Things like .toUpperCase() , .trim(), .includes(), .slice - these are all methods that live on String.prototype.

const name = "kanishk";
console.log(name.toUpperCase()); // "KANISHK"
console.log(name.includes("ani"));  // true

Simple, right? You write a string, call a method, and get a result. But these methods didn't always exist. JavaScript evolves constantly, and each new ECMAScript spec adds new ones. That's exactly where polyfills come in.

Why Would You Even Write a Polyfill?

A polyfill is basically you saying: "Hey, this built-in method might not exist in older environments - so let me implement it myself, just in case."

Think about it. You're building a web app that needs to run in older browsers. You use String.prototype.includes() freely in your code, but then someone opens your app in an old browser that doesn't support it - boom, everything breaks.

A polyfill patches that gap:

if (!String.prototype.includes) {
  String.prototype.includes = function(search, start) {
    return this.indexOf(search, start) !== -1;
  };
}

Interview insight: When an interviewer asks you to implement String.prototype.repeat from scratch, they're not checking if you memorised the spec. They're checking if you understand what the method actually does at a logical level. Can you think through the steps? Can you handle edge cases?

Implementing Common String Utilities

Let's go through the most commonly asked ones, one by one.

String.prototype.repeat
Repeats a string n times. Single concept, but the edge cases are what matter.

String.prototype.myRepeat = function(count) {
  if (count < 0) throw new RangeError("Invalid count value");
  if (count === 0) return "";

  let result = "";
  for (let i = 0; i < count; i++) {
    result += this;
  }
  return result;
};

console.log("ab".myRepeat(3)); // "ababab"

The logic is dead simple - loop count times, keep appending the string. The important bit is handling edge cases: negative count throws an error, zero returns an empty string.

String.prototype.includes
Checks if a string contains another string. This one's almost trivially easy because indexOf does the heavy lifting.

String.prototype.myIncludes = function(searchStr, position = 0) {
  return this.indexOf(searchStr, position) !== -1;
};

The concept: indexOf Returns -1 when the substring isn't found, and any other number when it is. We just convert that to a boolean.

startsWith and endsWith
These check if a string starts or ends with a particular substring. The key insight is uses slice to cut out the exact portion you want to compare.

String.prototype.myStartsWith = function(searchStr, position = 0) {
  return this.slice(position, position + searchStr.length) === searchStr;
};

String.prototype.myEndsWith = function(searchStr, endPosition = this.length) {
  const start = endPosition - searchStr.length;
  return this.slice(start, endPosition) === searchStr;
};

trim, trimStart, trimEnd
These remove whitespace from a string. This is a good one to know because it introduces regex patterns that come up again and again.

String.prototype.myTrim = function() {
  return this.replace(/^\s+|\s+$/g, "");
};

String.prototype.myTrimStart = function() {
  return this.replace(/^\s+/, "");
};

String.prototype.myTrimEnd = function() {
  return this.replace(/\s+$/, "");
};

The pattern ^\s+ matches whitespace at the beginning, and \s+$ matches it at the end. The | in myTrim just means "either/or".

padStart and padEnd
These pad a string to a specific length. The tricky part is when padString is longer than one character - you need to repeat it and then trim it down to exactly the right length.

String.prototype.myPadStart = function(targetLength, padString = " ") {
  if (this.length >= targetLength) return String(this);

  const padNeeded = targetLength - this.length;
  let padding = padString.repeat(Math.ceil(padNeeded / padString.length));
  padding = padding.slice(0, padNeeded);

  return padding + this;
};

console.log("5".myPadStart(3, "0")); // "005"

Common Interview String Problems

These are the classics - ones that show up across interviews at startups, mid-size companies, and big tech alike.

Reverse a String

Sounds too simple. Interviewers often ask for the manual approach because they want to see if you can work with indices.

function reverseString(str) {
  let result = "";
  for (let i = str.length - 1; i >= 0; i--) {
    result += str[i];
  }
  return result;
}

console.log(reverseString("hello")); // "olleh"

Check for Palindrome

Always clean the string first. Real-world strings have spaces, punctuation, mixed case - always handle that.

function isPalindrome(str) {
  const clean = str.toLowerCase().replace(/[^a-z0-9]/g, "");
  const reversed = clean.split("").reverse().join("");
  return clean === reversed;
}

console.log(isPalindrome("A man, a plan, a canal: Panama")); // true

Count Character Occurrences

The pattern count[char] = (count[char] || 0) + 1 is a one-liner you should have memorised.

function charCount(str) {
  const count = {};
  for (let char of str) {
    count[char] = (count[char] || 0) + 1;
  }
  return count;
}

console.log(charCount("hello"));
// { h: 1, e: 1, l: 2, o: 1 }

Check if Two Strings are Anagrams

function isAnagram(str1, str2) {
  if (str1.length !== str2.length) return false;

  const sort = s => s.toLowerCase().split("").sort().join("");
  return sort(str1) === sort(str2);
}

console.log(isAnagram("listen", "silent")); // true

The sorting approach is clean and readable. There's also a frequency counter approach (using charCount), which is O(n) vs O(n log n). Worth knowing both.

Longest Substring Without Repeating Characters

A sliding window classic. You're maintaining a window of unique characters - whenever a repeat shows up, you shrink the window from the left.

function lengthOfLongestSubstring(s) {
  let map = new Map();
  let maxLen = 0;
  let left = 0;

  for (let right = 0; right < s.length; right++) {
    if (map.has(s[right])) {
      left = Math.max(left, map.get(s[right]) + 1);
    }
    map.set(s[right], right);
    maxLen = Math.max(maxLen, right - left + 1);
  }

  return maxLen;
}

console.log(lengthOfLongestSubstring("abcabcbb")); // 3

Why Understanding Built-in Behaviour Actually Matters

You can use .includes() every day without ever thinking about how it works. That's totally fine for shipping features. But in interviews, this deeper understanding separates good candidates from great ones.

When you implement a polyfill from scratch, you're forced to think about:

  • What does this method return? A new string? A boolean? An index?

  • What happens at the boundaries? Empty strings, negative indices, undefined inputs.

  • What's the time complexity? Is my approach O(n)? O(n²)?

For example, most developers know str.includes(search) returns true or false.
But how many know it accepts a second argument - the position to start searching from? And what happens if you pass a RegExp as the search value? (It throws a TypeError.)

That kind of awareness doesn't come from memorising docs. It comes from implementing these things yourself, running them, breaking them, and fixing them.

Want More?

Blog: https://blogs.kanishk.codes/
Twitter: https://x.com/kanishk_fr/
LinkedIn: https://linkedin.com/in/kanishk-chandna/
Instagram: https://instagram.com/kanishk__fr/