I come across this code in jsGarden, and I cannot figure the meaning to chain call and apply together. Both will execute the function with a given context object, why it could be chained?
function Foo() {}
Foo.prototype.method = function(a, b, c) {
console.log(this, a, b, c);
};
// Create an unbound version of "method"
// It takes the parameters: this, arg1, arg2...argN
Foo.method = function() {
// Result: Foo.prototype.method.call(this, arg1, arg2... argN)
Function.call.apply(Foo.prototype.method, arguments);
};
It’s making a call to
callviaapply; that is, it’s usingcallto call a function (“method”), and it’s usingapplyto make the call because it’s got the arguments in the form of an (almost) array.So to take it apart:
That’s a reference to the
call()function available on all Function instances, inherited from the Function prototype.That’s a reference, via the reference to the
callfunction, toapply. Becauseapplyis referenced via thecallobject, when the call toapplyis made thethisvalue will be a reference to thecallfunction.So we’re invoking the
callfunction viaapply, and passingFoo.prototype.methodto be thethisvalue, and the arguments to “Foo.mmethod” as the arguments.I think it’s basically the same effect as this:
but I’ll have to try it to make sure. edit Yes that seems to be it. So I can summarize the point of that trick as being a way to invoke
apply()when the desiredthisvalue is the first element of the array holding the parameters. In other words, usually when you callapply()you’ve got the desiredthisobject reference, and you’ve got the parameters (in an array). Here, however, since the idea is that you pass in the desiredthisas a parameter, then it needs to be separated out in order for a call toapplyto be made. Personally I would do it as in my “translation” because it’s a little less mind-bending (to me), but I suppose one could get used to it. Not a common situation, in my experience.