Definition of the JavaScript this Keyword ? The object which called a function.

The JavaScript this keyword is used within any function scope or the global scope, and in each scope it receives a different value. The value of this inside a function, effectively depends on the object which called it.

What exactly is scope? Every function gets its own space in order to define variables and properties. When we want to access a certain variable, we must do it through the space in which it was defined. In JavaScript, when we haven?t defined a function, everything happens in global scope.

Code

1
2
3
4
5
6
var o={}; // declaring new object
o.name="moon";
o.method=function () {
  alert(this.name);
};
o.method();

We?ve defined a new object named o and a method which displays this.name. But where does this come from?

By calling o.method(), we?ll get the value “moon”. The process that?s taking place is the following:

  1. We create a variable of type string with the value "moon" and assign it to the name property of object o.
  2. We create a function with certain content and assign it as a method of o.
  3. We call the function so that o is the object that calls it.
  4. The function is called when this is actually a reference to o. We get o.name which is "moon".

It is important to note that a function is a variable in every sense. It contains expressions which we can call later on. Having this function assigned to o?s property “method” doesn?t connects the this variable inside it to o. The object doesn?t know about the contents of this function. The actual assignment of this only happens when the function is called, when this is translated as the object that called it, hence, o.

From here, we can make it a slightly more sophisticated:

1
2
3
4
5
6
7
8
9
10
var o={}; // declaring new object
o.name="moon";
o.method=function () {
  alert(this.name);
};

var x={};
x.name="sun";
x.method=o.method;
x.method();

We?ve declared a new object named x with a name property set to “sun”.

We?ve put a reference to the method we defined in o into x.method as well. When calling x.method, we won?t get, god forbid, “moon”, because there is no actual assignment to o. We get “sun” because x is the object that called the function, and the value of this is set to the object which called the function.

We can say that every JavaScript function has a hidden argument named this. Furthermore, with each call to the function, the argument is passed behind the scenes with the pointer to the object which called the function.

1
function f() { alert(this.name); }

Becomes:

1
function f(this) { alert(this.name); }

Meaning:

1
2
3
4
5
6
7
8
9
10
11
12
var o={}; // declaring new object

o.name="moon";
o.method=function (this) {
  alert(this.name);
};
o.method(o);

var x={};
x.name="sun";
x.method=o.method;
x.method(x);

In C++, the compiler adds an argument named this to every method in a class, which is an object of the class type, and effectively every call to a method becomes a call to the method together with that variable (please ignore C++ wrong syntax):

1
2
3
4
5
6
7
class Foo {
  string name="foo";
  string GetName() { return this.name; }
}

Foo o=new Foo();
string s=o.GetName();

Actually becomes something like:

1
2
3
4
5
6
7
class Foo {
  string name="foo";
  string GetName(Foo this) { return this.name; }
}

Foo o=new Foo();
string s=o.GetName(o);

More on this in C++ on Wikipedia

Changing the Value of this

It is possible to change the value of this, not by assignment (you cannot assign a value to this), but rather by calling a function via another object, as we did with x ? defining the function as a property of an object and calling the function through it.

JavaScript gives us the tools to call a function with a different this without too much effort, with the help of the methods call and apply. These two methods are quite similar: they are methods of a function (defined in Function.prototype) that take an object that should be the this and arguments, and call the function itself with these arguments. The difference is in how the arguments are passed ? call takes regular arguments (like params in C#), and apply takes the arguments as an array.

We?ll change the former code to work with call:

1
2
3
4
5
6
7
8
var o={}; // declaring new object
o.name="moon";
o.method=function () {
  alert(this.name);
};
var x={};
x.name="sun";
o.method.call(x);

What happens behind the scenes, sort of:

1
2
x.temporaryMethod=o.method;
x.temporaryMethod();

this and new Operators

A JavaScript function is not just a group of statements for later use, it also serves as a class; every function is also a class. We can create instances of a class.

1
2
3
function Foo(name) {
  this.name=name;
}

This function, like all functions, is also a class; we create an instance of it thus:

1
2
var instance=new Foo("bar");
alert(instance.name); // "bar"

What is actually happening behind the scenes? When we call new Foo(“bar”):

1
2
var instance={}; // declaring new, empty object
Foo.call(instance,name); // calling the constructor with the new object as this, and the argument "name"

Calling the constructor will call the expression:

1
this.name=name; // this is the "instance" object. assign name as the sent argument

The compiler creates a new, empty object and activates the class? constructor with call. This way, this will be a reference to the newly created object. The constructor calls the expressions and the references to this that it contains, and then new object is returned.

this and prototype

The prototype property is a class property, and whichever value we assign it will be available to all instances of the class. When accessing an object property, the existence of the property in the object will be checked first and, if not found, will be checked in the prototype of the class to which the object belongs (with Object being the basic class).

In JavaScript there are a number of pre-defined classes:

1
2
3
4
5
6
7
8
Object
Function
String
Number
Array
Date
Error
RegExp

We can extend any class with our own functions, and so each instance of the class will contain our extension.

C# contains a feature called extension method which extends the functionality of built-in classes such as int and string. This feature is also found in Ruby.

1
2
3
4
5
6
String.prototype.trim=function () {
  return this.replace(/^\s+|\s+$/g,"");
};
var s="    x        ";
alert("<"+s+">");
alert("<"+s.trim()+">");

After extending the prototype of the class String with a property named trim which is a function that trims blank spaces from the beginning and end of the string, we can access this method from any string. this in the function will contain the value of the string, because the string variable is the object that called the function.

this and the DOM

1
<div id="div" onclick="alert(this.innerHTML);">div</div>

The DOM knows to interpret the code thus:

1
2
3
div.onclick=function () {
  alert(this.innerHTML);
};

From here it looks familiar; onclick is defined as a property whose value is a function with use of this.

The browser will apply a ?listener? for mouse clicks. Once a click is received, it checks whether its location is on this div. If so, it checks whether the div has an onclick attribute, and then just calls the function like this:

1
div.onclick(event);

Thus, this contains a reference to the div.

Summary

this is a wide world in JavaScript. Comprehensive understanding of it will allow us to write shorter, more efficient and advanced code.

Comments