GregT
GregT

Reputation: 1320

JavaScript and 'this' inside immediately executed functions

I have been reading up on the intricacies of 'this' in JavaScript. Given this code:

$(document).ready(function() {
    console.dir(this);
    (function foo() {
        console.dir(this);
    })();
});

In Chrome, the console shows the first 'this' as an 'HTMLDocument' (as I expected), but the second 'this' is 'undefined'. Can someone point me to a good explanation of why?

Upvotes: 2

Views: 92

Answers (4)

JaredPar
JaredPar

Reputation: 754515

They way in which a javascript function is invoked changes the meaning of this inside of it. Here you've invoked a method which isn't associated with any object hence it has no this value to bind to.

In the first case the callback is being invoked via JQuery and they are manipulating the callback such that this points to the document DOM element. It's easy to visualize this as your callback being invoked with apply

yourCallback.apply(document, null);

You can fix the second version like so

$(document).ready(function() {
    console.dir(this);
    var that = this;
    (function foo() {
        console.dir(that);
    })();
});

Or another way using apply

$(document).ready(function() {
    console.dir(this);
    (function foo() {
        console.dir(this);
    }).apply(this, null);
});

Upvotes: 3

Simon Sarris
Simon Sarris

Reputation: 63802

If that code is put into the console of a page with jQuery loaded, the second "this" is DOMWindow, which is the global "this". It is not undefined.

There must be something else on your page.

Upvotes: 1

Matt Briggs
Matt Briggs

Reputation: 42158

The second this is in an anonymous function which has no context. this is always an implicit variable at the function level, so your inner functions this is shadowing the outer this

Upvotes: 0

Arnaud Le Blanc
Arnaud Le Blanc

Reputation: 99879

this is the context with which the current function has been called.

  • When calling a function with the object.method() syntax, object become the context.
  • When calling a function with the function() syntax, there is no context: it's null.

jQuery calls your ready function with document as the context. And you call your immediately executed function without context, which is why it's null.

You can do this:

// assign `this` to that so you can access `this` through `that`
var that = this; 
(function foo() {
    console.log(that);
}());

Or this:

// bind the function to `this` and then call it
$.proxy(function() { 
    console.log(this);
}, this)();

See jQuery.proxy.

Or even this:

// call the function with `this` as context
(function() { 
    console.log(this);
}).call(this);

See Function.call.

Upvotes: 1

Related Questions