String Polyfills and Common Interview Methods in JavaScript
JavaScript String Polyfills: Interview Questions & Implementation

As a web developer, 90% of what you do involves manipulating text. Whether you are formatting a user's name, checking if a password contains a special character, or extracting a domain name from a URL, you rely heavily on JavaScript's built-in String Methods (like .includes(), .slice(), or .toLowerCase()).
But what happens if you are in a technical interview and the interviewer says: "I want you to check if a string contains a specific word, but you are NOT allowed to use the built-in .includes() method."
They are asking you to write a Polyfill. Let's explore what polyfills are, why they are the ultimate test of your JavaScript knowledge, and how to conquer these common interview problems.
What string methods are?
A String Method is simply a built-in function that performs an operation on a piece of text.
Behind the scenes, JavaScript treats strings almost like arrays of characters. When you call "hello".toUpperCase(), the JavaScript engine runs a highly optimized C++ function under the hood to loop through each character and convert it to uppercase.
Why developers write polyfills?
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.
Imagine ES6 introduces a shiny new method called String.prototype.startsWith(). If a user visits your site on an ancient version of Internet Explorer, their browser will throw an error because it has no idea what .startsWith() means.
Developers write polyfills to say: "Hey browser, if you don't already have this method built-in, here is the manual logic to do it yourself."
Important Insight
Ye methods magic nahi hain
Ye internally logic + loops se bane hote hain
Why do interviewers care about Polyfills?
In modern development, tools like Babel handle polyfills for us automatically. So why do interviewers ask you to write them?
Because it proves you understand the engine. Anyone can memorize .repeat(3), but writing the manual logic proves you understand loops, edge cases, and the this keyword.
Implementing common string utilities
Polyfill = apna version of built-in method
- charAt — character access with bounds
Accessing a character by index. The key behaviour: returns an empty string (not undefined) when the index is out of bounds.
Implementing charAt
// Attaching to String prototype to make it a true polyfill
String.prototype.myCharAt = function(index) {
// 'this' refers to the string the method is called on
if (index < 0 || index >= this.length) {
return '';
}
return this[index];
};
function displayCharAt(str, index) {
const result = str.myCharAt(index);
// Using JSON.stringify to visualize empty strings clearly as ''
console.log(`myCharAt('\({str}', \){index}); // ${JSON.stringify(result)}`);
}
// Running your test cases
displayCharAt('hello', 1); // "e"
displayCharAt('hello', 10); // ""
displayCharAt('hello', -1); // ""
E:\Hitesh_Web_Dev_2026\blog_folder\JavaScript-blogs>node 24assign.js
myCharAt('hello', 1); // "e"
myCharAt('hello', 10); // ""
myCharAt('hello', -1); // ""
- trim — removing whitespace
The trick: walk from both ends, find the first non-whitespace character on each side, and slice. The insight is that spaces, tabs, and newlines all count as whitespace — and the check ' \t\n\r' should cover them.
Implementing trim
String.prototype.myTrim = function() {
let start = 0;
let end = this.length - 1;
// Checks for common whitespace characters
const isWhitespace = ch => ' \t\n\r\f\v'.includes(ch);
while (start <= end && isWhitespace(this[start])) {
start++;
}
while (end >= start && isWhitespace(this[end])) {
end--;
}
return this.slice(start, end + 1);
};
function displayTrimResult(str) {
const result = str.myTrim();
// JSON.stringify helps visualize the whitespace and empty strings
console.log(`myTrim(\({JSON.stringify(str)}) -> Result: \){JSON.stringify(result)}`);
}
// Running your test cases
displayTrimResult(' hello '); // "hello"
displayTrimResult('\n hi\t'); // "hi"
displayTrimResult(' '); // ""
E:\Hitesh_Web_Dev_2026\blog_folder\JavaScript-blogs>node 24assign.js
myTrim(" hello ") -> Result: "hello"
myTrim("\n hi\t") -> Result: "hi"
myTrim(" ") -> Result: ""
- repeat — concatenating a string n times
Straightforward to implement, but interviewers often probe the edge cases: what if n is 0? What if n is negative? What if n is not an integer?
Implementing repeat
String.prototype.myRepeat = function(count) {
if (count < 0) {
throw new RangeError('count must be non-negative');
}
let num = Math.floor(count);
let result = '';
// 'this' refers to the string being repeated
for (let i = 0; i < num; i++) {
result += this;
}
return result;
};
function displayRepeat(str, count) {
try {
const result = str.myRepeat(count);
console.log(`myRepeat('\({str}', \){count}); // '${result}'`);
} catch (e) {
console.log(`myRepeat('\({str}', \){count}); // Error: ${e.message}`);
}
}
// Running your test cases
displayRepeat('ab', 3); // 'ababab'
displayRepeat('hi', 0); // ''
displayRepeat('x', 2.9); // 'xx'
displayRepeat('no', -1); // Error: count must be non-negative
E:\Hitesh_Web_Dev_2026\blog_folder\JavaScript-blogs>node 24assign.js
myRepeat('ab', 3); // 'ababab'
myRepeat('hi', 0); // ''
myRepeat('x', 2.9); // 'xx'
myRepeat('no', -1); // Error: count must be non-negative
- startsWith and includes
Both are character-by-character comparisons at specific positions. includes tries every starting position; startsWith only checks from index 0 (or an optional offset).
Implementing startsWith and includes
// Polyfill for startsWith
String.prototype.myStartsWith = function(prefix, start = 0) {
// Handle cases where the start index is out of bounds
if (start < 0) start = 0;
if (prefix.length > this.length - start) return false;
for (let i = 0; i < prefix.length; i++) {
if (this[start + i] !== prefix[i]) return false;
}
return true;
};
// Polyfill for includes
String.prototype.myIncludes = function(search) {
// Empty search string is always true in native JS
if (search === '') return true;
for (let i = 0; i <= this.length - search.length; i++) {
// Reuse our custom startsWith logic
if (this.myStartsWith(search, i)) return true;
}
return false;
};
function displayResults(str, search, type) {
let result;
if (type === 'startsWith') {
result = str.myStartsWith(search);
console.log(`myStartsWith('\({str}', '\){search}'); // ${result}`);
} else {
result = str.myIncludes(search);
console.log(`myIncludes('\({str}', '\){search}'); // ${result}`);
}
}
// Running your test cases
displayResults('hello', 'hel', 'startsWith'); // true
displayResults('hello world', 'world', 'includes'); // true
displayResults('coding', 'don', 'includes'); // false
E:\Hitesh_Web_Dev_2026\blog_folder\JavaScript-blogs>node 24assign.js
myStartsWith('hello', 'hel'); // true
myIncludes('hello world', 'world'); // true
myIncludes('coding', 'don'); // false
- padStart — left-padding a string
A practical one that appears in formatting tasks: numbers as clock digits, fixed-width columns, ID generation. The logic: calculate how many characters are needed, build the padding from the fill character, then prepend.
Implementing padStart
String.prototype.myPadStart = function(targetLength, padChar = ' ') {
// If targetLength is less than current string, return original string
if (this.length >= targetLength) return String(this);
const padNeeded = targetLength - this.length;
let padding = '';
// Continue adding padChar until we meet or exceed padNeeded
while (padding.length < padNeeded) {
padding += padChar;
}
// Slice padding to exact size and prepend to 'this'
return padding.slice(0, padNeeded) + this;
};
function displayPad(str, targetLength, padChar) {
const result = str.myPadStart(targetLength, padChar);
console.log(`myPadStart('\({str}', \){targetLength}, '\({padChar || " "}') -> '\){result}'`);
}
// Running your test cases
displayPad('5', 3, '0'); // '005'
displayPad('hi', 6); // ' hi'
displayPad('hello', 3); // 'hello'
displayPad('7', 5, 'abc'); // 'abca7' (Handling multi-char padding)
E:\Hitesh_Web_Dev_2026\blog_folder\JavaScript-blogs>node 24assign.js
myPadStart('5', 3, '0') -> '005'
myPadStart('hi', 6, ' ') -> ' hi'
myPadStart('hello', 3, ' ') -> 'hello'
myPadStart('7', 5, 'abc') -> 'abca7'
Common interview string problems
The Problem: The .repeat(count) method takes a string and repeats it count number of times. Write a polyfill for it. The Logic (How it works conceptually):
We need to start with an empty string: "".
We need a loop that runs count times.
Every time the loop runs, we add our original string (this) to the new string.
We need to handle edge cases (What if they pass a negative number? What if count is 0?).
Why needed?
Older browsers support nahi karte
Interview me logic check hota hai
Deep understanding milti hai
Conclusion
Understanding built-in behavior is what separates junior developers from mid-level engineers.
When you just use built-in methods, JavaScript feels like magic. But when you write Polyfills, you pull back the curtain. You realize that strings are just character arrays, and methods are just cleverly disguised for loops.
Next time you use a built-in method like .split() or .includes(), take five minutes to ask yourself: "How would I write this from scratch using just a for loop?" It is the absolute best way to prepare for your upcoming technical interviews!
Real-Life Analogy
String methods = kitchen tools
Knife → slice
Mixer → transform
Filter → remove
Polyfill = khud tool banana
Quick Summary
String methods = built-in helpers
Polyfills = custom implementation
Interview focus:
reverse
palindrome
frequency
includes
Memory Trick
“Jo built-in hai, woh kisi ne manually banaya hai”
Tum bhi bana sakte ho



