CodeinWP CodeinWP

JavaScript ‘this’ in Different Contexts

JavaScript thisJavaScript has a reserved keyword called this that references something different depending on where you are in a JavaScript program.

In this post I’m going to summarize, by example, some different contexts and discuss what “this” would represent in each case. Note that all of these examples assume you’re developing client-side JavaScript in a browser.

In the Global Context

What happens if you reference this in the global context (i.e., not inside any function)?

console.log(this === window); // true

You can test this on any page in your dev tools by typing that line into the console.

As that code demonstrates, this in the global context refers to the window object. Look at the following code and the subsequent outputs:

this.message = "Check this out.";
window.message = "Check this out.";

console.log(this.message); // "Check this out."
console.log(window.message); // "Check this out."
console.log(message); // "Check this out."

You can view this code in action using this JS Bin.

So what’s going on here? The first two lines are doing the exact same thing — creating a global variable called “message” and setting its value to “Check this out.” This fact is demonstrated by the three console messages that follow, all showing the same result.

In Function Context

So what happens when you refer to this in the context of a function, or closure?

In a simple example with no futher nesting of functions, it will depend on whether you’re using strict mode:

function checkThisOut () {
  console.log(this === window); // true
  console.log(this); // object global
}

checkThisOut();

JS Bin example

As you can see, nothing’s changed from the global context (i.e. this still references the window object). Now let’s try in strict mode:

function checkThisOut () {
  "use strict";
  console.log(this === window); // false
  console.log(this); // undefined
}

checkThisOut();

JS Bin demo

If I understand correctly, as Nicholas Zakas points out, the behaviour shown in the “use strict” example is in order to prevent accidental globals. There could be more to it that I’m not fully understanding, but it seems that’s the main reason for the difference here.

In a Module Pattern

Recently I discussed the module pattern I’m currently using when writing JavaScript.

Let’s look at what this references in the context of such a pattern:

var s,
    PrimaryNameSpace = {

        settings : {
            first: true,
            second: false,
            foo: 'bar'
        },

        init: function () {
            console.log(this); // references PrimaryNameSpace
        },

        nextMethod: function () {
        },

        anotherMethod: function () {
        }

    };

PrimaryNameSpace.init();

JS Bin demo

In the module pattern context, inside any of the individual methods (that is, the functions), this will reference the entire module. In fact, if you view the console message created inside the init() method in your developer tools, you’ll see something like the following:

JavaScript this inside the module pattern

The console shows you an object (the namespace, or module), then you can drill down into the object to view the different methods, as well as all the values defined in the settings object.

Thus, inside the init() method, you can reference the modules and settings using this in the following manner:

/* ... other code here ...*/

        init: function () {
            s = this.settings;
            this.nextMethod();
            this.anotherMethod();
            console.log(s);            
        },

/* ... other code here ...*/

PrimaryNameSpace.init();

JS Bin demo

Using this to reference the other methods and the settings prevents us from having to write the references in long form. The following would be equivalent to what is written above:

/* ... other code here ...*/

        init: function () {
            s = PrimaryNameSpace.settings;
            PrimaryNameSpace.nextMethod();
            PrimaryNameSpace.anotherMethod();
            console.log(s);
        },

/* ... other code here ...*/

JS Bin demo

And in both cases, the console message would show:

The settings object in the module pattern

What About a Nested Function?

If however, you have an anonymous function inside one of the methods, then the value of this changes, and the module object is no longer accessible via this. So the long form syntax would be necessary, as shown here:

/* ... other code here ...*/

        init: function () {
            s = this.settings;
            (function () {
              this.nextMethod();
              // [object Window] has no method 'nextMethod'
            })();
        },

/* ... other code here ...*/

JS Bin demo

The comment I’ve inserted in the code above displays the message from the console, which demonstrates that inside the anonymous function, this is a reference to the global “window” object, rather than being a reference to the PrimaryNameSpace object.

And, as we saw earlier, using strict mode would make this undefined, rather than a reference to the global object.

Summing Up

If nothing else, this post should demonstrate that using this can be a useful shortcut. But all the while, keep in mind how the context can change the value of this as well how it behaves in strict mode.

I’ve only scratched the surface of this topic, so here are some further posts discussing the this keyword:

And if you have any corrections to what I’ve said, please add them to the comments and I’ll update accordingly.

18 Responses

  1. Dan says:

    This is not a correction, but a suggestion to include how ‘this’ behaves inside of events.
    For example (I’m going to use jQuery syntax to make the code more simple):

    $(‘#element’).on(‘click’, function () {
    $(this).css(‘color’, ‘red’);
    });

    In this case, ‘this’ refers to ‘#element’.

  2. Laurie says:

    The key to the `this` keyword isn’t where it’s used; it’s how a function that uses it is invoked. For example:

    var obj = { foo: function() { console.log(this); }};
    var foo = obj.foo;

    foo(); // -> window
    obj.foo(); // -> obj
    obj.foo.apply(Date); // -> Date

    The value of `this` will be bound to the value of the expression to the left of the ‘.’ in a function invocation; if there is no expression to the left of the ‘.’, as in the first example above, `this` will be bound to the global object (or to `nul` in strict mode); the value of `this` can also be explicitly bound using call() or apply() (final example above). The last is what’s going on with jQuery events. Then there’s bind(), which modifies the default binding when call()/apply() isn’t used…

    In other words, it’s not about how you write the code that uses the `this` keyword, it’s about how you *invoke* it. Ignoring bind(), the structure of the code you write is only relevant as far as it affects how you will normally invoke it.

  3. Jim Arment says:

    Love this stuff, and your module pattern write up. I didn’t know about the "use strict".

    When wanting the brevity of this inside of the nested function example, I like to store this inside of another short variable prior to the function (similar to what you do with the settings).

    
    init: function () {
    
        s = this.settings;
        host = this;
    
        (function () {
    
            host.nextMethod();
    
        })();
    }
    
  4. Javascripter says:

    No mention of call, apply and bind? I’m disappoint.

  5. baalin says:

    this is a very useful information and am learn from this article.and am want more information about this..

  6. Awesome post! Very useful for me! :D

  7. Binh Thanh Nguyen says:

    Thanks, nice post

  8. Rajeswari says:

    Hai, there is a small mistake in this documention , Here you mentioned Strict and Non strict mode….
    That Strict mode means if(this===window) and non strict mode means if(this==window) …But you mentioned === for both.

Leave a Reply

Comment Rules: Please use a real name or alias. Keywords are not allowed in the "name" field and deep URLs are not allowed in the "Website" field. If you use keywords or deep URLs, your comment or URL will be removed. No foul language, please. Thank you for cooperating.

Markdown in use! Use `backticks` for inline code snippets and triple backticks at start and end for code blocks. You can also indent a code block four spaces. And no need to escape HTML, just type it correctly but make sure it's inside code delimeters (backticks or triple backticks).