What in the global is this

Javascript has a special variable called this, which points to the current execution context. The execution context is the environment a function or method is executed in.

The value of this isn’t determined until run time. Since the same method or function can be executed in different contexts in the same program, the value of this in can also change.

In a browser, logging this in the global context logs window, which is the global object. The value of this can also be checked by comparing it to another value:

console.log(this === window); // true in the global scope

The value of this inside an object is the calling object, meaning the object itself. For example,

var obj = {
  prop: 5,
  showProp: function() {
    console.log(this.prop);
  },
  showThis: function() {
    console.log(this);
  },
}

obj.showProp(); // logs 5
obj.showThis(); // logs properties of obj

In the showProp method, this is used to refer to the current object obj. If this wasn’t used, it would look for a variable in the outer scope named prop. If there’s no variable with that name in an outer scope, it throws an error.

Since this is just a variable, it can be passed as an argument or returned from a function:

var obj = {
  prop: function() {
    return this;
  },
};

var obj2 = {
  log: function(arg) {
    console.log(arg);
  }
}

console.log(obj.prop()); // logs properties of obj
obj2.log(this);          // logs window

We can also add a method to obj which compares this to the object:

obj.compareThis = function() {
  console.log(this === obj);
};

obj.compareThis(); // logs true

Inside a method, this refers to the calling object. What does this refer to in a function?

function testThis() {
  console.log(this);
}

testThis(); // logs window

That makes sense if testThis was declared in the global scope, since testThis would be equivalent to

window.testThis();

because functions declared in the global scope get added as properties to the window object. What about this case:

var testThis = {
  prop: function() {
    (function() {
      console.log(this);
    })();
  },
};

testThis.prop(); // logs window

This logs window even though the inner function was called inside the testThis object.

This is somewhere the distinction between a method and a function is important. In a method, this refers to the calling object. In a function, this refers to the global object unless an explicit context was supplied to invoke the function. The rules for defining this are different than variable scoping.

As mentioned earlier, the value of this can change when the execution context changes. For example,

var testThis = {
  prop: function() {
    console.log(this);
  },
};

testThis.prop(); // logs properties of testThis

var extract = testThis.prop;
extract();       // logs window

This shows that when a method is taken from its original context and executed in a new context, this will be the new context.

Javascript has the methods call and apply that let you execute a function in a context you specify. They work the same way except for how they pass optional arguments. You can use them like this:

function logThis() {
  console.log(this);
}

var obj1 = {
  prop: 'first',
};

var obj2 = {
  prop: 'second',
  func: function() {
    console.log(this.prop);
  },
};

obj2.func();          // logs 'second'
obj2.func.call(obj1); // logs 'first'
logThis.call(obj2);   // logs the properties of obj2

This invoked a method from obj2 as if it belonged to obj1. The last line invoked a function in an explicit context (obj2) and it logs the properties of that object instead of window.

To conclude all of this, this is a variable that refers to the current execution context. Its value is assigned at run time. In an object method it points to the calling object. In a function, it points to the global object, which in a browser is window.