πŸš€ Array Method Polyfills: Understanding the Magic

🎯 Key Concepts to Remember

1. The Pattern

All three polyfills follow the same structure:

  • Validate the callback function
  • Create a result container (array for map/filter, any type for reduce)
  • Loop through the original array
  • Apply the callback function with proper parameters
  • Return the result

2. Important Details

  • Sparse arrays: We check i in this to handle arrays with missing indices
  • thisArg parameter: We use callback.call(thisArg, ...) to set the this context
  • Callback parameters: Each method passes different parameters:
    • map/filter: (element, index, array)
    • reduce: (accumulator, element, index, array)

3. The Mental Models

  • Map: Transform each item β†’ Same length, different values
  • Filter: Keep some items β†’ Shorter or same length, same values
  • Reduce: Combine all items β†’ Single result of any type

4. Why This Matters

Understanding polyfills helps you:

  • Debug issues with these methods
  • Understand performance implications
  • Write more efficient code
  • Handle edge cases better
  • Appreciate what the browser does for you!

πŸ—ΊοΈ Array.prototype.map

Concept:

Map creates a NEW array by transforming each element using a callback function. It's like having a factory that processes each item and outputs a modified version.

// Our custom map polyfill
Array.prototype.myMap = function(callback, thisArg) {
    // Check if callback is a function
    if (typeof callback !== 'function') {
        throw new TypeError(callback + ' is not a function');
    }
    
    // Create new array to store results
    const result = [];
    
    // Loop through each element
    for (let i = 0; i < this.length; i++) {
        // Check if index exists (sparse arrays)
        if (i in this) {
            // Call callback with: element, index, array
            result[i] = callback.call(thisArg, this[i], i, this);
        }
    }
    
    return result;
};

πŸ” Array.prototype.filter

Concept:

Filter creates a NEW array containing only elements that pass a test. Think of it as a bouncer that only lets certain items through based on your criteria.

// Our custom filter polyfill
Array.prototype.myFilter = function(callback, thisArg) {
    // Check if callback is a function
    if (typeof callback !== 'function') {
        throw new TypeError(callback + ' is not a function');
    }
    
    // Create new array for filtered results
    const result = [];
    
    // Loop through each element
    for (let i = 0; i < this.length; i++) {
        // Check if index exists
        if (i in this) {
            // Test element with callback
            if (callback.call(thisArg, this[i], i, this)) {
                // Only add if test passes
                result.push(this[i]);
            }
        }
    }
    
    return result;
};

⚑ Array.prototype.reduce

Concept:

Reduce takes an array and "reduces" it to a single value by applying a function that combines elements. Like a snowball rolling downhill, gathering more snow (data) as it goes.

// Our custom reduce polyfill
Array.prototype.myReduce = function(callback, initialValue) {
    // Check if callback is a function
    if (typeof callback !== 'function') {
        throw new TypeError(callback + ' is not a function');
    }
    
    // Handle empty arrays
    if (this.length === 0 && arguments.length < 2) {
        throw new TypeError('Reduce of empty array with no initial value');
    }
    
    let accumulator;
    let startIndex = 0;
    
    // Set up initial values
    if (arguments.length >= 2) {
        accumulator = initialValue;
    } else {
        // Find first valid element as initial value
        while (startIndex < this.length && !(startIndex in this)) {
            startIndex++;
        }
        accumulator = this[startIndex];
        startIndex++;
    }
    
    // Process each element
    for (let i = startIndex; i < this.length; i++) {
        if (i in this) {
            // Call callback with: accumulator, element, index, array
            accumulator = callback(accumulator, this[i], i, this);
        }
    }
    
    return accumulator;
};

✏️ Edit & Test Your Own Polyfills

Modify the polyfills below and test your changes instantly!

Map Polyfill

Filter Polyfill

Reduce Polyfill

πŸ§ͺ Interactive Testing Ground

Click the buttons to see our polyfills in action and compare with native methods!

Click any button above to see the polyfills in action!