Had a question about a implementation of bind function that I found on Mozilla’s site. For the most part it makes sense to me, but I cant figure out what this check is for…
this instanceof nop ? this : ( obj || {} )
in the bind function. Obviously its checking if ‘this’ is the empty function, but why would you need to bind the empty function. I have tried it in firebug, it works, but what is the point? Just trying to increase my javascript knowledge so any help would be appreciated.
if ( !Function.prototype.bind ) {
Function.prototype.bind = function( obj ) {
var slice = [].slice,
args = slice.call(arguments, 1),
self = this,
nop = function () {},
bound = function () {
return self.apply( this instanceof nop ? this : ( obj || {} ),
args.concat( slice.call(arguments) ) );
};
nop.prototype = self.prototype;
bound.prototype = new nop();
return bound;
};
}
Its allows you to call the bound function as a constructor without being bound to the original object. In other words the “bound” function will still work just like the original, unbound version if you call it with
new.Here’s an example:
How it works
To simplify the explanation, here’s a simplified version of the code that only binds
thisand doesn’t handle arguments or a missing obj parameter:The function that gets returned by
Function.prototype.bindbehaves differently depending on whether you use it as a function, or a constructor (see Section 15.3.4.5.1 and 15.3.4.5.2 of the ECMAScript 5 Language Specification). The primary difference, is that it ignores the “bound this” parameter when it’s called as a constructor (since inside a constructor,thisneeds to be the newly-created object). So theboundfunction needs a way to determine how it’s being called. For example,bound(123)vs.new bound(123)and setthisaccordingly.That’s where the
nopfunction comes in. It’s essentially acting as an intermediate “class” so thatboundextendsnopwhich extendsself(which is the functionbind()was called on). That part is set up here:When you call the bound function, it returns this expression:
this instanceof nopworks by following the prototype chain to determine the if any prototype ofthisis equal tonop.prototype. By settingnop.prototype = self.prototypeandbound.prototype = new nop(), any object created withnew bound()will be created with the original prototype fromselfviabound.prototype. So inside the function call,this instanceof nop(i.e. Object.getPrototypeOf(nop) == nop.prototype) istrueandselfgets called withthis(the newly created object).In a normal function call, ‘bound()’ (without
new),this instanceof nopwould be false, soobjgets passed as thethiscontext, which is what you would expect on a bound function.The reason for using the intermediate function is to avoid calling the original function (in the line
bound.prototype = new nop();), which may have side effects.