最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Understanding "this" keyword - Stack Overflow

programmeradmin2浏览0评论

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?

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?

Share Improve this question asked Jun 25, 2012 at 8:48 RaffaeleRaffaele 20.9k6 gold badges49 silver badges88 bronze badges 4
  • 1 How is that commit change related to your question at all? .apply was used to pass n amount of arguments to another function, not for its context forcing abilities. – Esailija Commented Jun 25, 2012 at 9:00
  • @Esailija, I think you got the point! – Raffaele Commented Jun 25, 2012 at 9:08
  • @Christoph I think he got the point. apply() was not used to force the context, since this was already placed correctly (and this answers my question) – Raffaele Commented Jun 25, 2012 at 9:12
  • The side effect of using .apply of course is that it's called as a property of .done/.fail instead of .deferred so you also need to pass the right context but it's not the main point of using it here. – Esailija Commented Jun 25, 2012 at 9:15
Add a comment  | 

5 Answers 5

Reset to default 5

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?

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.

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.

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.

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.

发布评论

评论列表(0)

  1. 暂无评论