Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Explanation of a line in MDN bind polyfill

Tags:

javascript

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.

like image 301
Ben Aston Avatar asked Jul 16 '16 15:07

Ben Aston


People also ask

What is polyfill for bind?

Polyfill is a browser fallback. If your browser don't have the bind() and you have to write your own bind() function, that is what we are going to do here. So, let's impolement our own bind() function. Let's have a look of actual bind(): let name={ fN:'Shubham', lN:'Verma' } let printN=function(){ console.

Why do we use the bind method?

We use the Bind() method to call a function with the this value, this keyword refers to the same object which is currently selected . In other words, bind() method allows us to easily set which object will be bound by the this keyword when a function or method is invoked.

What is the use of bind method in JavaScript?

The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

What is call apply bind in JavaScript?

Call invokes the function and allows you to pass in arguments one by one. Apply invokes the function and allows you to pass in arguments as an array. Bind returns a new function, allowing you to pass in a this array and any number of arguments.


1 Answers

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.

like image 87
t.niese Avatar answered Sep 20 '22 19:09

t.niese