WTF is this?

One of my PDR objective is to explain this in JavaScript to my colleagues that doesn't make them "want to kill". This is my attempt.

Open the console before clicking/tapping any buttons or you will not see anything.

In many object-oriented programming languages, this (also called self or Me) is a keyword that is used in instance methods to refer to the object on which they are working.
http://en.wikipedia.org/wiki/This_(computer_science)

In JavaScript this refers to different objects depending on where and how it is used. I'll dive straight into examples to illustrate each use.

In a normal function

When used in a normal function this refers to the global or window object.

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

In a normal function with "use strict";

When used in a normal function with strict mode turned on this is undefined.

				
(function() {
	"use strict";
	console.log(this);
})();
				
			

In a nested function

Nesting a function doesn't mean this will refer to the parent function. It's still the global object.

				
(function() {
	var nested_function = function() {
		console.log(this);
	}

	nested_function();
})();
				
			

In a nested function with "use strict";

Again, this is the same as a regular function with strict mode turned on, it is undefined.

				
(function() {
	"use strict";

	var sixth_function = function() {
		console.log(this);
	}

	sixth_function();
})();
				
			

In an function called by an event listener

When used in a function called by an event listener this is a reference to the element with the listener on it.

				
var test = document.getElementById('test');
var log_this = function() {
	console.log(this);
};

test.addEventListener('click', log_this, false);
				
			
then

In an object method

When this is used in a method of an object it references the object.

				
var firstObject = {
	first_method: function() {
		console.log(this);
	}
};

firstObject.first_method();
				
			

In a function nested in an object method

Being nested in an object method does not make a function special. It's still a regular function therefore will reference the global object or be undefined if strict mode is turned on.

				
var secondObject = {
	second_method: function() {
		var nested_function = function() {
			console.log(this);
		}

		nested_function();
	}
}

secondObject.second_method();
				
			

If there was no way round this it would be very annoying, but thankfully there is an easy way round it—just assign this to a variable and use it instead.

				
var secondObject = {
	second_method: function() {
		var that = this;
		var nested_function = function() {
			console.log(that);
		}

		nested_function();
	}
}

secondObject.second_method();
				
			

In the apply() or call() method of a function

When using apply() or call() the first parameter defines what this is, so any object can be referenced.

				
var applied_function = function() {
	console.log(this);
}

var fourthObject = {};

applied_function.apply(fourthObject);
				
			
				
var called_function = function() {
	console.log(this);
}

var fourthObject = {};

called_function.call(fourthObject);
				
			

In a constructor

When using a constructor to create objects this refers to the constructor.

				
function Person(firstname, birthyear, currentyear) {
	this.firstname = firstname;
	this.birthyear = birthyear;
	this.currentyear = currentyear;
}

var me = new Person('Derek', 1974, 2013);

console.log('Name: ' + me.firstname + ' Birth year: ' + me.birthyear + ' Current year: ' + me.currentyear);

Person.prototype.age = function() {
	console.log(this.currentyear - this.birthyear);
};

me.age();
				
			

In prototypal inheritance

When creating objects using prototypal inheritance this references the original object the new one is based on. Object.create is not supported in IE8 and below, and it only accepts one parameter.

				
var Person = {
	name: 'Derek',
	birthyear: 1974,
	currentyear: 2013
};

var me = Object.create(Person);

me.age = function() {
	console.log(this.currentyear - this.birthyear);
}

me.age();