Raffaele
Raffaele

Reputation: 20875

Understanding "this" keyword

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

Answers (5)

Esailija
Esailija

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

Nathan Wall
Nathan Wall

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

Denys Séguret
Denys Séguret

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

Willem Mulder
Willem Mulder

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

Shredderroy
Shredderroy

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

Related Questions