Implement Function.prototype.bind, including new
Writing a bind that fixes this and prepends arguments takes three lines. The reason this is an interview favourite is the other half of the spec: a bound function used as a constructor must ignore the bound receiver entirely, because new supplies its own this, and instances must still be instanceof the original function.
Implement myBind(fn, thisArg, ...boundArgs), where fn is an ordinary function declared with the function keyword. It returns a new function that, when called normally, invokes fn with this set to thisArg and with boundArgs followed by the call-time arguments, returning fn's result. The bound receiver wins permanently: calling the bound function as a method of some other object does not change this inside fn. When the bound function is called with new, thisArg is ignored and this inside fn is the newly constructed object; boundArgs are still prepended, the result is the new object (assuming fn returns nothing), the object inherits from fn.prototype so methods defined there are available, and instance instanceof fn is true. Your implementation must not use Function.prototype.bind, call or apply: one of the tests replaces all three with functions that throw.
Arguments
fnFunction- The function to bind. Must be a regular
functionsonewworks. thisArgany- The receiver for normal calls. Ignored under
new. ...boundArgsany[]- Arguments to prepend on every invocation of the bound function.
Returns
Function — A bound function callable normally or with new, with the correct receiver and prototype chain.
Examples
function greet(greeting) { return greeting + ", " + this.name; }
const hiAda = myBind(greet, { name: "Ada" }, "Hi");
hiAda(); // "Hi, Ada"function Point(x, y) { this.x = x; this.y = y; }
Point.prototype.sum = function () { return this.x + this.y; };
const BoundPoint = myBind(Point, null, 1);
const p = new BoundPoint(2);
p.x; // 1
p.y; // 2
p.sum(); // 3 — prototype methods still work
p instanceof Point; // trueUnder new, the bound receiver is ignored and the fresh object stays on the correct prototype chain.
What it has to do
- Set
thistothisArgfor a normal call and prependboundArgs. - Keep the bound receiver even when the bound function is called as another object's method.
- Under
new, ignorethisArgand use the freshly constructed object asthis. - Under
new, keepfn.prototypein the instance's prototype chain soinstance instanceof fnholds and prototype methods work. - Work when
Function.prototype.bind,callandapplyhave been replaced with throwing stubs.
Notes
new.targetinside the bound function tells you whether it was called withnew. Branch on it to decide whether to usethisorthisArg.- Point
bound.prototype = Object.create(fn.prototype)so instances inherit fromfn.prototype. Reach forReflect.applyinstead of.call/.apply— those are the ones the test stubs out.
Stuck? The javascript course covers everything this challenge needs.
- 1.binds the receiver
- 2.prepends the bound arguments
- 3.the bound receiver cannot be overridden later
- 4.works as a constructor with new
- 5.does not rely on bind, call or apply
These assertions run in your browser the moment you hit Run. Pass all of them to claim the XP.
Discussion
Sign in to postNo comments yet. Be the first to say something.