JS PollyFillls Machine Coding Interview
This blog will give you the experience of how Pollyfills questions are asked in the interviews.

Engineer @Ciena | Software Engineering | Full Stack Development | Typescript , Java, React Node | DSA LeetCode (600+) | System Design |
In this blog you will get an understanding of how to approach a PollyFill implementation question in an interview. I will include proper examples of some popular questions which which will help you relate the different scenarios of how and what to answer in the interview.
1. Array.prototype.includes (Easy)
💻 Implement a polyfill for Array.prototype.includes without using indexOf or built-in array methods.
if( !Array.prototype.myIncludes){
Array.prototype.myIncludes = function(searchElement , startIndex = 0){
startIndex = startIndex>=0 ? startIndex: Math.max( 0, this.length-Math.abs(startIndex));
for( let i = startIndex; i< this.length; i++){
if( this[i] == searchElement || ( Number.isNaN(this[i]) && Number.isNaN(searchElement)) ){
return true;
}
// if (Object.is(this[i], searchElement)) return true; (Alternative)
}
return false;
}
}
❓ Conceptual Questions:
How does
Array.prototype.includesdiffer fromArray.prototype.indexOf?Answer
includesreturnstrueorfalsedepending on whether the element exists in the array, whileindexOfreturns the index of the first occurrence or-1if the element is not found.includesperforms a strict equality check (===), but it correctly identifiesNaN, whereasindexOfdoes not becauseNaN !== NaN.indexOfis useful for getting the position of an element, whileincludesis better for simple existence checks.
Why does
Array.prototype.includesreturntrueforNaN, whileindexOfdoes not?Answer
indexOfrelies on strict equality (===), andNaN !== NaN, soindexOf(NaN)always returns-1.includesuses theSameValueZeroalgorithm, which treatsNaNas equal toNaN.
How does
startIndexwork when it is negative?Answer
If
startIndexis negative then we have to search the element fromthis.length-startIndexto the end of the array. If thestartIndexis very low value then we will have to search the entire array.const arr = [10, 20, 30, 40, 50]; console.log(arr.includes(30, -2)); // false (starts searching from index 3)
2. Object.assign (Medium)
❓ Conceptual Questions:
What is
Object.assignused for?Object.assignis used to copy enumerable own properties from one or more source objects to a target object.It performs a shallow copy, meaning nested objects are still referenced rather than deeply copied.
It is commonly used for merging objects, creating object clones, and adding properties dynamically.
What happens if
Object.assignreceivesnullorundefinedas a target or source?If the target is
nullorundefined, it throws aTypeErrorbecause assignment requires an object.If a source is
nullorundefined, it is ignored, and no properties are copied.
Object.assign({}, null, { a: 1 }); // { a: 1 }
Object.assign(null, { a: 1 }); // TypeError
How does
Object.assignhandle inherited properties?Object.assignonly copies own properties of source objects, not properties from the prototype chain.It copies both string keys and symbol keys, but only if they belong to the object itself.
const proto = { inherited: 'I am inherited' };
const obj = Object.create(proto);
obj.own = 'I am ram';
const copy = Object.assign({}, obj);
console.log(copy); // { own: 'I am ram' } (inherited property is not copied)
💻 Implement a polyfill for Object.assign
if( !Object.myAssign){
Object.myAssign = function(target, ...sources){
if(target == null)
throw new TypeError("target cannot be null as we cannot convert null/undefined to an object. Pass {} as target in the calling function.")
let res = Object(target);
for( let source of sources){
if( source != null){
// In the object there can be keys / Symbols / Inherited properties
// Object.assign only copies the keys and symbols and not inherited properties.
for(let key of Object.keys(source) ){
res[key] = source[key];
}
for(let symbol of Object.getOwnPropertySymbols(sources)){
res[symbol] = source[symbol];
}
}
}
return res;
}
}
const obj1 = { a: 1 };
const obj2 = { b: 2, [Symbol('c')]: 3 };
const obj3 = Object.create({ inherited: 4 }, { d: { value: 5, enumerable: true } });
console.log(Object.myAssign({}, obj1, obj2, obj3));
// { a: 1, b: 2, d: 5, [Symbol(c)]: 3 }
Bonus :
Read about Enumerable Properties
How Properties Become Enumerable or Not?
Properties defined using object literals (
{}) orObject.defineProperty():By default, properties in object literals are enumerable.
If defined using
Object.defineProperty(), you must explicitly setenumerable: trueif you want them to be enumerable.
const obj1 = { x: 10 }; // enumerable by default
const obj2 = {};
Object.defineProperty(obj2, 'y', { value: 20, enumerable: false });
console.log(Object.keys(obj1)); // ['x']
console.log(Object.keys(obj2)); // [] (because 'y' is non-enumerable)
Built-in properties and methods (e.g., from prototypes) are usually non-enumerable:
- Many built-in properties, like
lengthin arrays and methods on prototypes, are non-enumerable.
- Many built-in properties, like
console.log(Object.keys([])); // [] (does not include 'length')
console.log([].propertyIsEnumerable('length')); // false
Symbol properties are not enumerable by default in
Object.keys()andfor...in:- But they can be retrieved using
Object.getOwnPropertySymbols().
- But they can be retrieved using
const sym = Symbol('hidden');
const obj = { visible: 1, [sym]: 2 };
console.log(Object.keys(obj)); // ['visible'] (Symbol property is skipped)
console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(hidden)]
Summary
| Method | Includes Enumerable Properties? | Includes Non-Enumerable? | Includes Symbols? |
Object.keys(obj) | ✅ Yes | ❌ No | ❌ No |
Object.values(obj) | ✅ Yes | ❌ No | ❌ No |
Object.entries(obj) | ✅ Yes | ❌ No | ❌ No |
Object.getOwnPropertyNames(obj) | ✅ Yes | ✅ Yes | ❌ No |
Object.getOwnPropertySymbols(obj) | ❌ No | ❌ No | ✅ Yes |
for...in | ✅ Yes (own + inherited) | ❌ No | ❌ No |
👉 Enumerable properties are those that appear when iterating with for...in or Object.keys(), unless explicitly made non-enumerable using Object.defineProperty()! 🚀




