Have you ever wondered how the filter function works in JavaScript? I recently came accross that problem. After a few days of procrastination and fear, and reading the documentation and articles (one here on this platform), I can say I finally have a grasp of how it works under the hood.
Array.prototype.myFilter = function (callbackFn, thisArg) {
// Check if the callback is a function; if not, throw a TypeError.
if (typeof callbackFn !== "function") {
throw new TypeError("This is not a function");
}
// This is the backbone of the filter function.
// 'this' refers to the value that called 'myFilter'.
// Object(this) ensures 'this' is always treated as an object.
const O = Object(this);
// Get the length of the array-like object.
// The `>>> 0` coercion forces the length into a sane, non-negative
// 32-bit unsigned integer, even if the real value is malformed.
const len = O.length >>> 0;
// Initialize an empty array that values passing the test will be appended to.
let result = [];
// Two separate indexes: k tracks position in the original array,
// N tracks position in the result array. Filter skips holes in sparse
// arrays, so without two separate counters, the result could end up
// with gaps instead of being densely packed.
let k = 0; // current index in the original array
let N = 0; // next index to write to in the result array
while (k < len) {
// Check if a property exists at index k. Using `in` (rather than
// Object.hasOwn) is deliberate — it also checks the prototype chain,
// matching the spec's HasProperty behavior exactly.
if (k in O) {
let kValue = O[k];
// Run the test, coercing the result to a real boolean.
const testPassed = Boolean(callbackFn.call(thisArg, kValue, k, O));
if (testPassed) {
result[N] = kValue;
N++;
}
}
k++; // always advance k, whether or not the value existed or passed
}
return result; // the new array containing only the elements that passed the test
};
For an in-depth explanation, please refer to this article by Priya Khanna
Top comments (0)