Reputation: 55729
The MDN bind polyfill is shown below.
I am trying to work out the purpose of
this instanceof fNOP ? this : oThis
in the fToBind.apply
invocation.
I can't get my head around it. Can someone help shed some light?
Function.prototype.bindMdn = function(oThis) {
if (typeof this !== 'function') {
// closest thing possible to the ECMAScript 5
// internal IsCallable function
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
var aArgs = Array.prototype.slice.call(arguments, 1)
, fToBind = this
, fNOP = function() {}
, fBound = function() {
return fToBind.apply(this instanceof fNOP ? this : oThis, aArgs.concat(Array.prototype.slice.call(arguments)));
}
;
if (this.prototype) {
// Function.prototype doesn't have a prototype property
fNOP.prototype = this.prototype;
}
fBound.prototype = new fNOP();
return fBound;
};
It seems to be a short-circuit if an instance of the bound function is supplied as the target when invoking the bound function, but the typeof check should catch this, so I don't understand its presence.
Link to the MDN page:
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind
Edit: This is a different question from the suggested duplicate. The suggested duplicate asks why fNOP
is needed. I fully grok that.
This question is why the instanceof
check is needed and what function it serves. I present my short-circuit hypothesis above, together with a reason why that doesn't fully make sense.
Upvotes: 8
Views: 610
Reputation: 40842
If you use the result of a .bind
to create a new instance with new
:
function TestClass(a,b,c,d) {
}
var TestClassBound = TestClass.bindMdn(null, 1, 2, 3);
new TestClassBound();
Then this instanceof fNOP
is true
.
The typeof this !== 'function'
is just there to test if it was called a regular way on a function and not with call
or apply
or to make sure it was not copied to another objects prototype. So it only prevent something like
Function.prototype.bind.call("Not a function", 1, 2, 3);
Or
var testObj = {};
testObj.bind = Function.prototype.bind;
testObj.bind(1,2,3);
For every regular call of bind
on a function the typeof this
will always be function
.
So the typeof this !== 'function'
is to check if the object bind
is called is really a function.
And the this instanceof fNOP
within the fBind
ensures that the behaviour is correct when the result of the binding is used.
Upvotes: 6