this variable in JavaScript

Execution Context (Aka the this variable)


One of the hardest things to understand in JavaScript is the this variable, also known as the execution context. The this variable refers to the current object of which the called method is currently associated with.

const obj = {
  name: 'mari',
  speak: function() {
    console.log(this.name);
  },
};
obj.speak();

Try it!

The this variable is dynamically scoped, this means that it’s changed and doesn’t use the data that you might think it does when you use it.

the this variable


The this variable is a part of the EcmaScript spec, that means that it’s part of the language but its implementation depends on what environment you’re running your JavaScript code in. In the browser it refers to the window object, in node it refers to the global object. Open the node repl and type this, you’ll see the global object printed.

$ node
> this
{ DTRACE_NET_SERVER_CONNECTION: [Function],
  DTRACE_NET_STREAM_END: [Function],
  DTRACE_HTTP_SERVER_REQUEST: [Function],
  DTRACE_HTTP_SERVER_RESPONSE: [Function],
  DTRACE_HTTP_CLIENT_REQUEST: [Function],
  DTRACE_HTTP_CLIENT_RESPONSE: [Function],
  global: [Circular],
  process:
  process {
    title: 'node',

Some important methods on functions


JavaScript functions also have methods on them and the most important ones are bind, call, and apply, see another way to call a function:

const f = function(g) {
  console.log(g);
};
// call just takes all the arguments you give it
// and passes it to the function you are calling with .call
f.call(null, 'hello');

You can also use .apply but for apply you need to give an array of arguments.

const f = function(g, h) {
  console.log(g + h);
};
f.apply(null, ['hello', 'world']);

Controling execution context


Notice that for both .call and .apply we gave null. This means that we aren’t going to provide a custom execution context, that the function will get to use whatever the this variable would have been. Now we will control the execution context:

const obj = {
  name: 'mari',
  speak: function() {
    console.log(this.name);
  },
};
const other_obj = { name: 'nane' };
obj.speak.call(other_obj);

Run this code and you’ll see that nane is printed to the screen, not mari.

Binding a context for a function


Now we will talk about the most powerful and important method on functions, .bind. The big annoyance in JavaScript is that the execution context, the this variable that you end up using at runtime is not always the one you think will be used. This is because the this variable is dynamically scoped, not lexically scoped. To make sure that our function uses the execution content that we want used we have to use .bind, .bind creates a new function that uses the execution context that you provide.

const obj = {
  name: 'aram',
};
// At the top level this refers to the global object
this.name = 'gohar';
const g = function(last_name) {
  // This is using ES6 string interpolation, aka the ${}
  return `${this.name.toUpperCase()} ${last_name}`;
};
const f = g.bind(obj);
console.log(f('baz'));

So f is a new function which is bound, we did a bind on g, to the JavaScript object obj, we can also do other wacky things with .bind like partial function application.

Useful for Partial function application


Partial function application is like making a new function from another function but where some of the arguments are used with other values; its clearer with an example.

const obj = {
  name: 'aram',
};
// At the top level this refers to the global object
this.name = 'gohar';
const g = function(last_name, age) {
  return `${this.name} ${last_name} ${age}`;
};
// The first argument must always be the new execution context
// and the other arguments end up being the
// arguments of the original function
const f = g.bind(obj, 'baz');
console.log(f(22));

See how 'baz' ends up taking the argument value of last_name, this is positional.

Be sure to read over and over, MDN article on this variable


Check out our forums for more discussions, and if you like what you read, then join iterate hackerspace for a community of programmers in Yerevan for coding workshops, coding community.


Comments powered by Talkyard.