Tomatoes
Tomatoes

Reputation: 91

"this" inside a closure function

this inside a closure. It is important to take note that closures cannot access the outer function’s this variable by using the this keyword because the this variable is accessible only by the function itself, not by inner functions.

For example:

var user = {
tournament:"The Masters",
data      :[
{name:"T. Woods", age:37},
{name:"P. Mickelson", age:43}
],

clickHandler:function () {
// the use of this.data here is fine, because "this" refers to the user object, and data is a property on the user object.

this.data.forEach (function (person) {
// But here inside the anonymous function (that we pass to the forEach method), "this" no longer refers to the user object.
// This inner function cannot access the outer function's "this"

console.log ("What is This referring to? " + this); //[object Window]

console.log (person.name + " is playing at " + this.tournament);
// T. Woods is playing at undefined
// P. Mickelson is playing at undefined
})
}

}

user.clickHandler(); // What is This referring to? [object Window]

My question is: Why is this of some function below referring to jquery's button object instead of the window Object. Afterall, the callback function (some function) is still inside another function (click).

$("button").click (some function);

Also, I took a look at another similar question on SO but I am still none the wiser. "this" keyword inside closure

Upvotes: 0

Views: 614

Answers (2)

elrick
elrick

Reputation: 681

You have it right that the 'this' keyword which refers to the object on which the currently executing method has been invoked. So in your first example the clickHandler() function is going to refer to the user object.

Now in terms of jQuery when you are inside of a callback function 'this' is referring to the the 'DOM' element. The reason for this as i understand is that jQuery returns a object from its internal 'jQuery' code that maintains the reference to the element that was in context being the 'DOM' element using call() and apply(). I believe to maintain it. Doing so also allows you to accomplish that chaining of actions like ("button").click(somefunction).fadeIn() for example.

If you make your own jquery function such as $.fn.somefunction = function() {...} this refers to a jQuery object at this point.

There might be a better why to accomplish this but I quickly changed your code using call() to make is refer to your user object.

var user = {
    tournament:"The Masters",
    data      :[
        {name:"T. Woods", age:37},
        {name:"P. Mickelson", age:43}
    ],

    clickHandler: function () {
    // the use of this.data here is fine, because "this" refers to the user object, 
    // and data is a property on the user object.

    this.data.forEach (function (person) {
        // But here inside the anonymous function (that we pass to the forEach method),
        //"this" no longer refers to the user object.
        // This inner function cannot access the outer function's "this"

        //Use call to make this refer to your user object
        that = Object.call(this, user);

         console.log ("What is This referring to? " + that); //[object Object]

         console.log (person.name + " is playing at " + that.tournament);
         // T. Woods is playing at undefined
         // P. Mickelson is playing at undefined
        })
     }

    }

user.clickHandler(); // What is This referring to? [object Object]

Another thing is in Javascript the forEach function takes a second parameter that will be used as the object to reference for 'this' so another way you could have done it. Now this refers to user object.

....

this.data.forEach (function (person) {
    // But here inside the anonymous function (that we pass to the forEach method),
    //"this" no longer refers to the user object.
    // This inner function cannot access the outer function's "this"

    //Use call to make this refer to your user object

     console.log ("What is This referring to? " + this); //[object Object]

     console.log (person.name + " is playing at " + this.tournament);
     // T. Woods is playing at Masters
     // P. Mickelson is playing at Masters
     //pass user as the object the second parameter
    }, user)
 }

}

Check out the explanation of this on the jquery site here is a link.

http://learn.jquery.com/javascript-101/this-keyword/

Upvotes: 1

T.J. Crowder
T.J. Crowder

Reputation: 1074058

My question is: Why is this of some function below referring to jquery's button object instead of the window Object.

Because jQuery calls the handler setting the meaning of this explicitly, via the Function#call function (or it could be Function#apply, I'd have to look at the jQuery source).

Here's a simple example of using call:

function foo() {
    console.log("this.answer = " + this.answer);
}

var obj = {answer: "42"};
foo.call(obj); // The first argument is used as `this` during the call

That will output

this.answer = 42

Upvotes: 6

Related Questions