2754. Bind Function to Context
Problem Description
This problem asks you to implement a polyfill for JavaScript's bind method. The goal is to add a method called bindPolyfill to all functions that mimics the behavior of the native bind method.
When bindPolyfill is called on a function with an object as an argument, it should return a new function where the this context is permanently set to the provided object.
Key requirements:
- Add 
bindPolyfillmethod to theFunction.prototypeso all functions have access to it - The method takes one parameter: an object that will become the 
thiscontext - It returns a new function that, when called, executes the original function with the bound 
thiscontext - The returned function should pass along any arguments it receives to the original function
 - You cannot use the built-in 
Function.bindmethod 
Example behavior:
Without binding:
function f() {
  console.log('My context is ' + this.ctx);
}
f(); // Output: "My context is undefined"
With binding using bindPolyfill:
function f() {
  console.log('My context is ' + this.ctx);
}
const boundFunc = f.bindPolyfill({ "ctx": "My Object" });
boundFunc(); // Output: "My context is My Object"
The solution uses Function.prototype to add the method to all functions. Inside bindPolyfill, it returns an arrow function that captures the original function (this) and the object to bind. When the returned function is called, it uses call to invoke the original function with the specified this context and forwards any arguments using the spread operator (...args).
Intuition
To understand how to build a bind polyfill, we need to think about what binding actually does: it creates a new function that "remembers" a specific this context, no matter how that function is eventually called.
The key insight is that we need to create a closure - a function that captures and preserves values from its surrounding scope. When bindPolyfill is called, we want to:
- Capture the original function - We need to preserve reference to the function we're binding (which is 
thisinside thebindPolyfillmethod) - Capture the target object - We need to preserve the object that should become the new 
thiscontext - Return a wrapper function - This new function will call the original with the correct context
 
Since we can't use the native bind, we need another way to explicitly set the this context when calling a function. JavaScript provides call and apply methods for this exact purpose. The call method allows us to invoke a function with a specific this value.
Why use an arrow function for the returned wrapper? Arrow functions are ideal here because:
- They automatically capture variables from their enclosing scope (creating the closure we need)
 - They don't have their own 
thisbinding, sothisinside the arrow function refers to thethisfrombindPolyfill(which is our original function) 
The spread operator (...args) handles the forwarding of arguments elegantly - whatever arguments are passed to the bound function get collected into an array and then spread back out when calling the original function.
This approach essentially manually implements what the native bind does under the hood: creating a closure that preserves both the function and its intended context, then using call to apply that context when the function is invoked.
Solution Approach
The implementation extends the Function.prototype to add the bindPolyfill method to all functions in JavaScript. Here's how the solution works step by step:
1. Extending Function.prototype
Function.prototype.bindPolyfill = function (obj) {
    // implementation here
};
By adding a method to Function.prototype, every function in JavaScript automatically inherits this method. This allows any function to call bindPolyfill.
2. The method signature
The method accepts a single parameter obj which is the object that will become the this context for the bound function.
3. Returning a new function
return (...args) => {
    return this.call(obj, ...args);
};
The method returns an arrow function that:
- Uses the rest parameter syntax 
...argsto collect all arguments passed to it into an array - Inside this arrow function, 
thisrefers to the original function (the onebindPolyfillwas called on) because arrow functions don't have their ownthisbinding 
4. Using call to set context
this.call(obj, ...args)
The call method is used to invoke the original function with:
objas thethiscontext (first parameter tocall)...argsspread out as individual arguments (remaining parameters tocall)
5. TypeScript declarations
type Fn = (...args) => any;
declare global {
    interface Function {
        bindPolyfill(obj: Record<any, any>): Fn;
    }
}
These TypeScript declarations:
- Define 
Fnas a function type that can accept any arguments and return any value - Extend the global 
Functioninterface to include thebindPolyfillmethod - Specify that 
bindPolyfilltakes a record (object) and returns a function 
The beauty of this solution is its simplicity - it leverages JavaScript's closure mechanism and the call method to achieve the same effect as the native bind method in just a few lines of code.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through a concrete example to see how the bindPolyfill solution works:
// Step 1: Define a function that uses 'this'
function greet(greeting, punctuation) {
  return greeting + ', ' + this.name + punctuation;
}
// Step 2: Create an object to bind as context
const person = { name: 'Alice' };
// Step 3: Call bindPolyfill
const boundGreet = greet.bindPolyfill(person);
When bindPolyfill is called:
- Inside 
bindPolyfill,thisrefers to thegreetfunction - The 
objparameter contains{ name: 'Alice' } - An arrow function is created and returned:
(...args) => { return this.call(obj, ...args); // 'this' is captured as the greet function // 'obj' is captured as { name: 'Alice' } } 
Now when we call the bound function:
// Step 4: Call the bound function with arguments const result = boundGreet('Hello', '!');
Here's what happens internally:
- The arrow function receives arguments: 
['Hello', '!'] - These are collected into 
argsarray via rest parameters - The arrow function executes 
greet.call(person, 'Hello', '!') - Inside 
greet,thisis nowpersonobject - The function accesses 
this.namewhich is'Alice' - Returns: 
'Hello, Alice!' 
Even if we try to change the context later:
const anotherPerson = { name: 'Bob' }; boundGreet.call(anotherPerson, 'Hi', '?'); // Still returns "Hi, Alice?"
The bound context remains person because it was captured in the closure when bindPolyfill was first called. The arrow function always uses the original obj (person) when calling the original function, regardless of how the bound function itself is invoked.
Solution Implementation
1# Type definition: Fn represents a callable that accepts any arguments and returns any type
2# In Python, we use Callable from typing module for this purpose
3from typing import Any, Callable, Dict
4
5# Define type alias for a function that accepts any arguments and returns any type
6Fn = Callable[..., Any]
7
8# Custom implementation of bind functionality as a polyfill
9# Since Python doesn't have prototypes like JavaScript, we'll create a wrapper class
10class FunctionWithBindPolyfill:
11    """Wrapper class to add bindPolyfill method to functions"""
12
13    def __init__(self, func: Callable):
14        """Initialize with the original function"""
15        self.original_function = func
16
17    def bindPolyfill(self, obj: Dict[Any, Any]) -> Fn:
18        """
19        Custom polyfill method that mimics the behavior of native bind()
20        Takes an object to be used as 'this' context and returns a new function
21
22        Args:
23            obj: Dictionary/object to be used as the context for the function
24
25        Returns:
26            A new function with the bound context
27        """
28        # Store reference to the original function
29        original_function = self.original_function
30
31        # Return a new function that maintains the bound context
32        def bound_function(*args: Any, **kwargs: Any) -> Any:
33            """
34            Inner function that calls the original with the specified context
35
36            Args:
37                *args: Variable positional arguments
38                **kwargs: Variable keyword arguments
39
40            Returns:
41                Result of calling the original function with bound context
42            """
43            # In Python, we simulate 'this' binding by passing obj as first argument
44            # if the original function expects it (like a method would)
45            if hasattr(original_function, '__self__'):
46                # If it's already a bound method, call normally
47                return original_function(*args, **kwargs)
48            else:
49                # Simulate JavaScript's call() by passing obj as self if needed
50                # For regular functions, just call with arguments
51                try:
52                    # Try calling as a method with obj as self
53                    return original_function(obj, *args, **kwargs)
54                except TypeError:
55                    # If that fails, call as a regular function
56                    return original_function(*args, **kwargs)
57
58        # Return the new bound function
59        return bound_function
60
61
62# Alternative implementation using a decorator approach
63def add_bind_polyfill(func: Callable) -> Any:
64    """
65    Decorator to add bindPolyfill method to a function
66
67    Args:
68        func: The function to enhance with bindPolyfill
69
70    Returns:
71        The function with bindPolyfill method added
72    """
73    # Create a wrapper class instance for the function
74    wrapper = FunctionWithBindPolyfill(func)
75
76    # Copy the original function's attributes
77    wrapper.__name__ = func.__name__
78    wrapper.__doc__ = func.__doc__
79
80    # Make the wrapper callable like the original function
81    wrapper.__call__ = func
82
83    # Return the wrapper with bindPolyfill method
84    return wrapper
851import java.lang.reflect.Method;
2import java.util.function.Function;
3
4/**
5 * Interface representing a function that accepts variable arguments and returns Object
6 * This is the Java equivalent of TypeScript's Fn type
7 */
8@FunctionalInterface
9interface Fn {
10    Object apply(Object... args);
11}
12
13/**
14 * Custom function wrapper class that provides bind functionality
15 * Since Java doesn't allow extending native classes like Function,
16 * we create a wrapper class to achieve similar behavior
17 */
18class FunctionWrapper {
19    // The original method to be invoked
20    private final Method method;
21    // The object instance that owns the method
22    private final Object instance;
23
24    /**
25     * Constructor to wrap a method with its instance
26     * @param method The method to be wrapped
27     * @param instance The object instance that owns the method
28     */
29    public FunctionWrapper(Method method, Object instance) {
30        this.method = method;
31        this.instance = instance;
32    }
33
34    /**
35     * Implementation of bindPolyfill that creates a new function with a fixed 'this' context
36     * @param obj The object to be used as 'this' context when the function is called
37     * @return A new function (Fn) that calls the original method with the bound context
38     */
39    public Fn bindPolyfill(Object obj) {
40        // Store reference to the original method
41        final Method originalFunction = this.method;
42
43        // Return a new function that maintains the bound context
44        // Using lambda expression which is equivalent to arrow function in TypeScript
45        return (Object... args) -> {
46            try {
47                // Make the method accessible in case it's private
48                originalFunction.setAccessible(true);
49                // Call the original method with the specified 'this' context (obj) and arguments
50                return originalFunction.invoke(obj, args);
51            } catch (Exception e) {
52                // Handle reflection exceptions
53                throw new RuntimeException("Error invoking bound method", e);
54            }
55        };
56    }
57}
581#include <functional>
2#include <any>
3#include <vector>
4#include <memory>
5
6// Template class to implement a custom bind polyfill
7// This mimics JavaScript's Function.prototype.bind behavior
8template<typename ReturnType, typename... Args>
9class BindPolyfill {
10private:
11    // Store the original function
12    std::function<ReturnType(Args...)> original_function;
13    // Store the bound object context
14    std::any bound_context;
15
16public:
17    // Constructor that takes a function and an object to bind as context
18    BindPolyfill(std::function<ReturnType(Args...)> func, std::any obj)
19        : original_function(func), bound_context(obj) {}
20
21    // Overloaded function call operator to make this callable
22    // Applies the original function with the bound context
23    ReturnType operator()(Args... args) {
24        // In C++, we simulate the 'this' binding by passing the bound object
25        // as the first parameter if needed, or using it as context
26        return original_function(args...);
27    }
28};
29
30// Helper function to create a bindPolyfill
31// Takes a callable and an object to bind as context
32template<typename Func, typename Context>
33auto bindPolyfill(Func func, Context obj) {
34    // Return a lambda that captures both the function and the context
35    // This lambda forwards all arguments to the original function
36    return [func, obj](auto&&... args) -> decltype(auto) {
37        // If the function is a member function, it would need special handling
38        // For general functions, we simply call with the provided arguments
39        return func(std::forward<decltype(args)>(args)...);
40    };
41}
42
43// Alternative implementation using std::bind-like approach
44template<typename ReturnType, typename ClassType, typename... Args>
45class MemberFunctionBinder {
46private:
47    // Pointer to member function
48    ReturnType (ClassType::*member_func_ptr)(Args...);
49    // Pointer to the object instance
50    ClassType* object_instance;
51
52public:
53    // Constructor taking member function pointer and object pointer
54    MemberFunctionBinder(ReturnType (ClassType::*func)(Args...), ClassType* obj)
55        : member_func_ptr(func), object_instance(obj) {}
56
57    // Call operator that invokes the member function on the bound object
58    ReturnType operator()(Args... args) {
59        // Call the member function with the bound object instance
60        return (object_instance->*member_func_ptr)(args...);
61    }
62};
63
64// Utility function to create a member function binder
65// Binds a member function to a specific object instance
66template<typename ReturnType, typename ClassType, typename... Args>
67auto bindPolyfill(ReturnType (ClassType::*func)(Args...), ClassType* obj) {
68    // Return a lambda that captures the member function and object
69    return [func, obj](Args... args) -> ReturnType {
70        // Invoke the member function on the bound object
71        return (obj->*func)(args...);
72    };
73}
741// Type definition for a function that accepts any arguments and returns any type
2type Fn = (...args: any[]) => any;
3
4// Extend the global Function interface to include our custom bindPolyfill method
5declare global {
6    interface Function {
7        // Custom polyfill method that mimics the behavior of native bind()
8        // Takes an object to be used as 'this' context and returns a new function
9        bindPolyfill(obj: Record<any, any>): Fn;
10    }
11}
12
13// Implementation of bindPolyfill on Function prototype
14// This method creates a new function with a fixed 'this' context
15Function.prototype.bindPolyfill = function (obj: Record<any, any>): Fn {
16    // Store reference to the original function
17    const originalFunction = this;
18
19    // Return a new arrow function that maintains the bound context
20    return (...args: any[]): any => {
21        // Call the original function with the specified 'this' context and arguments
22        return originalFunction.call(obj, ...args);
23    };
24};
25Time and Space Complexity
Time Complexity: O(1)
- The 
bindPolyfillmethod creates and returns a new arrow function, which is a constant-time operation - The returned function itself, when invoked, uses 
call()to execute the original function with the bound context - The 
call()method hasO(1)overhead for setting up the execution context - The actual time complexity when the bound function executes depends on the original function's implementation, but the binding operation itself is 
O(1) 
Space Complexity: O(1)
- The 
bindPolyfillmethod creates a closure that captures:- The reference to the original function (
this) - The reference to the object (
obj) 
 - The reference to the original function (
 - These are fixed-size references regardless of input size
 - The arrow function returned occupies constant space
 - The 
...argsspread operator in the returned function will create a new array when the function is called, but this is part of the execution space, not the binding space - Overall space complexity for the binding operation is 
O(1) 
Common Pitfalls
1. Losing the Original Function Reference
One of the most common mistakes is not properly capturing the original function reference before returning the new bound function. Developers often make this error:
Incorrect Implementation:
Function.prototype.bindPolyfill = function(obj) {
    return function(...args) {
        return this.call(obj, ...args); // ERROR: 'this' is undefined or wrong context
    };
};
Problem: Using a regular function instead of an arrow function causes this inside the returned function to refer to the wrong context (or be undefined in strict mode) rather than the original function.
Solution: Use an arrow function to preserve the lexical this:
Function.prototype.bindPolyfill = function(obj) {
    return (...args) => {
        return this.call(obj, ...args); // Correct: 'this' refers to the original function
    };
};
2. Not Handling Constructor Calls
The native bind method handles the case where the bound function is called with new. The polyfill should account for this:
Incomplete Implementation:
Function.prototype.bindPolyfill = function(obj) {
    return (...args) => {
        return this.call(obj, ...args);
    };
};
Problem: Arrow functions cannot be used as constructors, so new boundFunc() will throw an error.
Better Solution:
Function.prototype.bindPolyfill = function(obj) {
    const originalFunc = this;
    return function(...args) {
        if (new.target) {
            // Called with 'new'
            return new originalFunc(...args);
        }
        return originalFunc.call(obj, ...args);
    };
};
3. Forgetting to Return the Result
A subtle but critical mistake is forgetting to return the result of the function call:
Incorrect:
Function.prototype.bindPolyfill = function(obj) {
    return (...args) => {
        this.call(obj, ...args); // Missing return statement
    };
};
Problem: The bound function will always return undefined regardless of what the original function returns.
Solution: Always return the result:
Function.prototype.bindPolyfill = function(obj) {
    return (...args) => {
        return this.call(obj, ...args); // Properly returns the result
    };
};
4. Not Preserving Partial Application
The native bind method supports partial application (pre-filling arguments), but basic polyfills often miss this:
Limited Implementation:
Function.prototype.bindPolyfill = function(obj) {
    return (...args) => {
        return this.call(obj, ...args);
    };
};
Full Implementation with Partial Application:
Function.prototype.bindPolyfill = function(obj, ...boundArgs) {
    return (...args) => {
        return this.call(obj, ...boundArgs, ...args);
    };
};
5. TypeScript Type Safety Issues
When implementing in TypeScript, not properly typing the return value can lead to loss of type information:
Poor Typing:
Function.prototype.bindPolyfill = function(obj: any): any {
    return (...args: any[]) => {
        return this.call(obj, ...args);
    };
};
Better Typing:
type Fn<T = any> = (...args: any[]) => T;
declare global {
    interface Function {
        bindPolyfill<T>(this: Fn<T>, obj: Record<any, any>): Fn<T>;
    }
}
Function.prototype.bindPolyfill = function<T>(obj: Record<any, any>): Fn<T> {
    return (...args: any[]): T => {
        return this.call(obj, ...args);
    };
};
These pitfalls highlight the importance of understanding JavaScript's execution context, the differences between arrow functions and regular functions, and the full behavior of the native bind method when creating a polyfill.
How does merge sort divide the problem into subproblems?
Recommended Readings
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion If you prefer videos here's a video that explains recursion in a fun and easy way Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask him
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!