Reputation: 20875
In this commit there is a change I cannot explain
deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments );
becomes
deferred.done( arguments ).fail( arguments );
AFAIK, when you invoke a function as a member of some object like obj.func()
, inside the function this
is bound to obj
, so there would be no use invoking a function through apply()
just to bound this
to obj
. Instead, according to the comments, this was required because of some preceding $.Callbacks.add
implementation.
My doubt is not about jQuery, but about the Javascript language itself: when you invoke a function like obj.func()
, how can it be that inside func()
the this
keyword is not bound to obj
?
Upvotes: 16
Views: 629
Reputation: 140210
My doubt is not about jQuery, but about the Javascript language itself: when you invoke a function like obj.func(), how can it be that inside func() the this keyword is not bound to obj?
Well, the only way this is possible is if obj.func
references a bound
function, then it doesn't matter how you call it. In that case it doesn't matter how you call the function, whether you do obj.func()
, func()
, func.call({})
, func.apply({})
doesn't matter at all. I'm not sure how the commit is related to this, however.
To clarify, I am answering the quoted question interpreted as:
Given a call signature like: obj.func()
, how is it possible that this
is not obj
inside the called function for the call?
Upvotes: 5
Reputation: 6766
While the other answers deal with your question about the this
keyword, they don't answer your question of why apply
is being used. Here's the kicker: apply
is not being used to set the this
keyword in that example. Instead, it's being used to pass arguments
as the arguments of the done
and fail
functions.
Take this example:
var x = {
a: function(a1, a2, a3) {
console.log(a1, a2, a3);
}
}
function callA() {
x.a.apply(x, arguments);
x.a(arguments);
}
callA('red', 'blue', 'green');
If you execute this code you should see the difference between x.a.apply(x, arguments);
and x.a(arguments);
. In the first one, a1
, a2
, and a3
are the respective colors "red", "blue", and "green". In the second one, a1
is an array-like object [ "red", "blue", "green" ]
and a2
and a3
are undefined
.
Likewise, in your posted example, apply
is being used to pass the arguments
object correctly, not to set the this
keyword.
Upvotes: 5
Reputation: 382092
A function is always called with a receiver, called this
inside the function, which is given at call.
When you're writing
obj.someFunc = function() {...
you're not saying that someFunc must have as receiver obj, you're just saying that obj has a property called someFunc whose value is a function.
If you do
var aFunc = obj.someFunc;
like is done in many places (referencing of callback for example) and after that
aFunc();
the receiver (this
) is in this case the window.
That's because functions, in javascript, contrary to languages like java, are "first class" objects, meaning in particular that you can pass them as values and aren't bound to a unique prespecified receiver.
Upvotes: 1
Reputation: 13994
That is only possible by referencing the function from another Object like so
obj2.func = obj.func;
obj2.func(); // 'this' now refers to obj2
var func2 = obj.func;
func2(); // 'this' now refers to the global window object
or by calling .apply() or .call() to bind this
to any arbitrary object.
Upvotes: 2
Reputation: 2920
The shorthand version I use is that this
in JavaScript always refers to the object of which the currently executing function is a method--except in the special case when the method is a callback, when this
refers to the object to which the callback is bound (e.g. a button).
Edit: note that a global function is like a method of the window
object.
This QuirksMode page helped me when I was learning about it.
Upvotes: 1