String Polyfills and Common Interview Methods in JavaScript

Almost every JavaScript developer uses .toUpperCase(), .trim(), or .includes() without a second thought — call the method, get the result, move on. But interviews (and genuine understanding) tend to ask a more interesting question: if these methods didn't exist, could you build them yourself? That's exactly what a polyfill is, and walking through a handful of them is one of the most reliable ways to sharpen the string-manipulation logic that shows up constantly in coding interviews.
What String Methods Are
A string method is a built-in function attached to every string value in JavaScript, letting you inspect or transform text without writing that logic yourself:
"hello world".toUpperCase(); // "HELLO WORLD"
" hi there ".trim(); // "hi there"
"javascript".includes("script"); // trueThese methods exist on String.prototype — a shared object that every string automatically has access to, which is exactly the mechanism polyfills use to add their own custom versions, covered next.

Why Developers Write Polyfills
A polyfill is custom code that reimplements a feature — recreating behavior that either doesn’t exist yet in an environment, or, for learning purposes, recreating something that does already exist, purely to understand how it works underneath.
Historical reasons
Polyfills originally became popular as a practical necessity — newer JavaScript methods weren’t available in older browsers, so developers wrote their own versions to fill the gap (hence “poly-fill”) until support caught up everywhere.
Learning and interview reasons
Today, writing a polyfill for an existing method — even one every browser already supports — is one of the most effective ways to actually understand what a method is doing, character by character, rather than treating it as an opaque black box. This is precisely why interviewers ask for them: “can you write .trim() yourself?" tests whether you understand strings as sequences of characters, not just whether you've memorized a method name.

Implementing Simple String Utilities
Let’s build a few common string methods from scratch, attaching each to String.prototype the same way the real ones work.
A custom .trim()
String.prototype.myTrim = function () {
let start = 0;
let end = this.length - 1;
while (this[start] === " ") start++;
while (this[end] === " ") end--;
return this.slice(start, end + 1);
};
" hello ".myTrim(); // "hello"The logic: walk inward from both ends, skipping spaces, and slice out just the meaningful middle section.
A custom .reverse() (strings don't have one built in)
String.prototype.myReverse = function () {
let result = "";
for (let i = this.length - 1; i >= 0; i--) {
result += this[i];
}
return result;
};
"hello".myReverse(); // "olleh"A custom .includes()
String.prototype.myIncludes = function (search) {
for (let i = 0; i <= this.length - search.length; i++) {
if (this.slice(i, i + search.length) === search) {
return true;
}
}
return false;
};
"javascript".myIncludes("script"); // trueA custom .toUpperCase() (a simplified version, for ASCII letters)
String.prototype.myToUpperCase = function () {
let result = "";
for (let char of this) {
const code = char.charCodeAt(0);
if (code >= 97 && code <= 122) {
result += String.fromCharCode(code - 32);
} else {
result += char;
}
}
return result;
};
"hello".myToUpperCase(); // "HELLO"This one is especially instructive — it reveals that “uppercase” is really just a character-code shift for the basic Latin alphabet, something the built-in method handles far more robustly (across every language and script), but the core idea is the same.

Common Interview String Problems
Beyond recreating existing methods, these classic problems come up constantly — because they all test the same underlying skill: reasoning about strings as sequences of characters.
Reverse a string
Covered above — the classic first question, testing basic iteration and index handling.
Check if a string is a palindrome
function isPalindrome(str) {
const cleaned = str.toLowerCase().replace(/[^a-z0-9]/g, "");
return cleaned === cleaned.split("").reverse().join("");
}
isPalindrome("A man a plan a canal Panama"); // trueCount vowels in a string
function countVowels(str) {
const vowels = "aeiouAEIOU";
let count = 0;
for (let char of str) {
if (vowels.includes(char)) count++;
}
return count;
}
countVowels("Hello World"); // 3Find the first non-repeating character
function firstUniqueChar(str) {
for (let char of str) {
if (str.indexOf(char) === str.lastIndexOf(char)) {
return char;
}
}
return null;
}
firstUniqueChar("aabbcddd"); // "c"Capitalize the first letter of every word
function capitalizeWords(str) {
return str
.split(" ")
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
.join(" ");
}
capitalizeWords("hello there friend"); // "Hello There Friend"
