Understanding how this works in JavaScript is fairly simple. Knowing what this points to however… that is much more difficult. Scope and context become important concepts to understand. Knowing exactly what this points to and why within each function/method in your JavaScript code can be utterly confusing. Hopefully the rules and corresponding examples below provide clarity on this.

TL;DR — The four rules presented for determining what this in JavaScript points to boil down to one simple question: What is the calling object?

In JavaScript functions don’t know where they live. They only know how they are called.

Alexis Abril, Advanced JS Fundamentals to jQuery & Pure DOM Scripting (What is “this”: 9:09–9:13)

  1. Whenever a function is contained in the global scope, the value of this inside of that function will be the window object.

    // Basic Function
    // --------------
    function greetMe(name) {
        console.log('Hello ' + name);
        console.log(this);
    }
    
    greetMe('John');
    Screenshot of console output from this in JavaScript rule 1 example

    Functions within the global scope are in fact methods on the window object. So, calling greetMe('john'); is no different than calling window.greetMe('john'); Therefore, this inside of the greetMe function points to window.

  2. Whenever a function is called by a preceding dot, the object before that dot is this.

    // Object Method
    // -------------
    var greetMe = {
        greeting: 'Hello ',
        speak: function(name) {
            console.log(this.greeting + name);
            console.log(this);
        }
    }
    
    greetMe.speak('John');
    Screenshot of console output from this in JavaScript rule 2 example

    This example is similar to what we saw above with window.greetMe. Here, instead of window we have the greetMe object on the left of the dot. Therefore, this inside of the speak method points to greetMe.

    // Method Assignment
    // -----------------
    var greeting = 'Salutations ',
        greet = greetMe.speak;
    
    greet('John');
    Screenshot of console output from this in JavaScript rule 2 example

    While this example appears to break rule 2, it doesn’t because it actually applies to rule 1. In this example, we establish two global variables: greeting and greet. Remember, since these variables are declared in the global scope, they are actually just properties on the window object. Therefore, when greet is called, while it points to the greetMe.speak method, it is executed in the context of the window object. It would be as if you executed window.greet('John');. Therefore, this inside of the greet function points to window.

  3. Whenever a constructor function is used, this refers to the specific instance of the object that is created and returned by the constructor function.

    // Constructor Function
    // --------------------
    function GreetMe(name) {
        this.greeting = 'Hello ';
        this.name = name;
        this.speak = function() {
            console.log(this.greeting + this.name);
            console.log(this);
        }
    };
    
    var greetJohn = new GreetMe('John');
    var greetJane = new GreetMe('Jane');
    
    greetJohn.speak();
    greetJane.speak();
    Screenshot of console output from this in JavaScript rule 3 example

    In the example above, both the greetJohn and greetJane variables are assigned a unique object returned by the GreetMe constructor function. Therefore, this inside of the speak method points to the unique GreetMe object instance stored in the variable on which the speak method is being called. This is evident by looking at the name property on the GreetMe object.

    // Constructor Function Prototype Method
    // -------------------------------------
    GreetMe.prototype.sayGoodbye = function() {
        console.log('Goodbye ' + this.name);
        console.log(this);
    };
    
    greetJohn.sayGoodbye();
    greetJane.sayGoodbye();
    Screenshot of console output from this in JavaScript rule 3 example

    This example is similar to the previous. The difference is that instead of a method being called that exists directly on the object instance, the method is called from the constructor function’s prototype. However, the context of this does not change ‐ it still points to the unique GreetMe object stored in the variable on which the sayGoodbye method is being called.

  4. Whenever JavaScript’s call or apply method is used, this is explicitly defined.

    // Using call/apply
    // ----------------
    greetJohn.sayGoodbye.call(greetJane);
    greetJane.sayGoodbye.apply(greetJohn);
    Screenshot of console output from this in JavaScript rule 4 example

    JavaScript’s call and apply methods allow you to execute a function in a different context. The first argument passed to either of these methods explicitly sets what this points to. Because call and apply are explicit, they present the clearest case of what this points to. This is evident by looking at the name property logged to the console by each invocation of the sayGoodbye method.

Posted by: John Dugan

Comments

  • Hey John, you say:

    “The difference is that instead of a method being called that exists directly on the object instance, the method is called from the constructor function’s prototype.”

    I don’t think that this is the case, since the constructor function’s prototype is actually the function prototype.

    The “prototype” property points to the prototype of the instantiated object, but it is not a prototype of the constructor function.

    Otherwise, great article!

  • Hey Ivan,

    Thanks for the comment. Drrrrp. Yeah, that merits some correction. Thanks for the catch :-).

    I’m sure at the time I was trying to convey that the method does not exist directly on the object – being replicated on each instance. Rather, it is shared across all instances via the prototype.

    For anyone seeing this comment who is a bit confused about prototypes, have a look at the first couple slides here: https://john-dugan.com/wp-content/uploads/2015/04/oloo-slides.pdf