# String Polyfills and Common Interview Methods in JavaScript

So at some point in your JavaScript journey, someone's going to ask you in an interview " can you implement ***indexOf*** without using it ? " or "write your own **trim** function."

And if you've only ever *used* these methods without thinking about what they're actually doing underneath, that question hits different.

That's what this post is about understanding the logic behind string methods well enough to rebuild them yourself which also happens to be exactly what interviews test.

## What String Methods Actually Are

String methods are built-in functions that JavaScript gives you on every string. Things like .toUpperCase(), .includes(), .trim(), .slice() they live on String.prototype, which means every string you create automatically has access to them.

```javascript
const name = "ankur"
console.log(name.toUpperCase()) // ANKUR
```

You didn't write toUpperCase JavaScript shipped it. Most developers use these methods every day without ever thinking about what's happening inside them.

That's fine for production code. But for interviews and for actually understanding the language you want to know the logic.

## What is a Polyfill ?

A polyfill is code you write to replicate something built-in usually because either the built-in doesn't exist in older environments, or you want to understand how it works from scratch. The word itself comes from "Polyfilla" a wall-filling product. You're filling in a gap.

In interview context, polyfills are really just logic exercises. "Implement this without using the native version." The point isn't that the native version is bad it's to test whether you understand what's happening under the hood.

## Implementing Common String Utilities

### Your Own includes

The built-in **includes** checks if a substring exists inside a string. How would you do that without it ?

```javascript
function myIncludes(str, target) {
  for (let i = 0; i <= str.length - target.length; i++) {
    if (str.slice(i, i + target.length) === target) {
      return true
    }
  }
  return false
}

console.log(myIncludes("javascript", "script")) // true
console.log(myIncludes("javascript", "python")) // false
```

Slide a window of **target.length** across the string. At each position, check if that chunk matches the target. If it does at any point found it. If you reach the end without a match not there.

### Your Own indexOf

Similar to **includes** but instead of returning true/false, return the position where the match starts. Return -1 if not found same as the built-in.

```javascript
function myIndexOf(str, target) {
  for (let i = 0; i <= str.length - target.length; i++) {
    if (str.slice(i, i + target.length) === target) {
      return i;
    }
  }
  return -1
}

console.log(myIndexOf("javascript", "script")) // 4
console.log(myIndexOf("javascript", "python")) // -1
```

Same sliding window. Just return the index instead of true.

### Your Own trim

trim removes whitespace from both ends of a string. Not from the middle just the edges.

```javascript
function myTrim(str) {
  let start = 0
  let end = str.length - 1

  while (start <= end && str[start] === " ") start++
  while (end >= start && str[end] === " ") end--

  return str.slice(start, end + 1)
}

console.log(myTrim("  hello world  ")) // "hello world"
console.log(myTrim("   ankur"))        // "ankur"
```

Two pointers one from the left, one from the right. Move the left pointer forward while you're hitting spaces. Move the right pointer backward while you're hitting spaces. Slice what's in between.

### Your Own repeat

```javascript
function myRepeat(str, times) {
  if (times <= 0) return ""

  let result = ""
  for (let i = 0; i < times; i++) {
    result += str
  }
  return result
}

console.log(myRepeat("ha", 3)) // hahaha
console.log(myRepeat("ab", 0)) // ""
```

Simple loop. Build up the result string by appending **str** once per iteration.

### Your Own startsWith

```javascript
function myStartsWith(str, target) {
  return str.slice(0, target.length) === target
}

console.log(myStartsWith("javascript", "java")) // true
console.log(myStartsWith("javascript", "node")) // false
```

Cut the front of the string to the same length as the target. If it matches starts with it.

### Your Own endsWith

```javascript
function myEndsWith(str, target) {
  return str.slice(str.length - target.length) === target
}

console.log(myEndsWith("javascript", "script")) // true
console.log(myEndsWith("javascript", "java"))   // false
```

Same idea but from the other end. Slice the tail of the string and compare.

## Common Interview String Problems

Beyond polyfills, these are the string problems that come up constantly in interviews.

### Reverse a String

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

console.log(reverseString("ankur")) // rukna
```

Loop from the end to the start, build a new string. The one-liner version is str.split("").reverse().join("") but if they say "without built-ins", use the loop.

### Check if a String is a Palindrome

A palindrome reads the same forwards and backwards. "racecar", "madam", "level".

```javascript
function isPalindrome(str) {
  let left = 0
  let right = str.length - 1

  while (left < right) {
    if (str[left] !== str[right]) return false
    left++
    right--
  }
  return true
}

console.log(isPalindrome("racecar")) // true
console.log(isPalindrome("ankur"))   // false
```

Two pointers from both ends moving toward the middle. If they ever don't match not a palindrome. If they meet in the middle without a mismatch it is.

### Count Vowels in a String

```javascript
function countVowels(str) {
  const vowels = "aeiouAEIOU"
  let count = 0

  for (let char of str) {
    if (vowels.includes(char)) count++
  }
  return count
}

console.log(countVowels("javascript")) // 3
console.log(countVowels("Ankur"))      // 2
```

Loop through each character. Check if it's in your vowel string. Increment counter if yes.

### Find the Most Repeated Character

```javascript
function mostRepeated(str) {
  const freq = {}

  for (let char of str) {
    freq[char] = (freq[char] || 0) + 1
  }

  let maxChar = ""
  let maxCount = 0

  for (let char in freq) {
    if (freq[char] > maxCount) {
      maxCount = freq[char]
      maxChar = char
    }
  }

  return maxChar
}

console.log(mostRepeated("javascript")) // a
```

Build a frequency map first count how many times each character appears. Then scan the map for the highest count.

### Check if Two Strings are Anagrams

Two words are anagrams if they have the exact same characters in a different order. "listen" and "silent" for example.

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

  const freq = {}

  for (let char of str1) {
    freq[char] = (freq[char] || 0) + 1
  }

  for (let char of str2) {
    if (!freq[char]) return false
    freq[char]--
  }

  return true
}

console.log(isAnagram("listen", "silent")) // true
console.log(isAnagram("hello", "world"))   // false
```

Different lengths can't be anagrams check that first. Then count character frequencies in the first string. Go through the second string, decrement for each match. If a character isn't in the map or runs out not an anagram.

## Why This Actually Matters

Knowing that .trim() exists and using it in production code is completely fine. That's the right thing to do. Built-in methods are optimized, tested, and maintained.

But understanding *how* trim works the two-pointer approach, moving from edges inward tells you something about the underlying logic. And that understanding transfers. The same two-pointer technique shows up in palindrome checks, in array problems, in a dozen other places. It's a pattern, not just an answer.

Interviews aren't really testing whether you've memorized polyfill implementations. They're testing whether you can reason through a problem without reaching for a shortcut. Can you break it down? Can you think about edge cases? Can you explain your approach? That only comes from understanding what the built-ins are doing, not just that they exist.
