Register to get access to free programming courses with interactive exercises

Context (This) JS: Introduction to Object Oriented Programming (OOP)

If you want to study OOP in JavaScript thoroughly, you need to understand the concept of this. Nearly everything else is based on context, including how methods and classes work.

What complicates things a bit is that context works differently for normal and arrow functions. And since arrow functions appeared later in the language, you need to start learning context with regular functions in order to get to grips with the topic. A little reminder of what such features look like:

// Defining the arrow function and assigning it to a constant
const f = () => 'i am an arrow function';

// Defining a normal anonymous function
function() {
  return 'i am a regular function without name';
}

// Defining an ordinary named function
function f() {
  return 'i am a regular function with name';
}

In this lesson, we'll only look at normal functions, arrow functions will be in one of the next lessons. Normal functions work with context the same way, whether they're named or not.

In JavaScript, functions behave like data: they can be written to variables, constants, and even object properties. Functions written inside object properties are called methods:

const company = { name: 'Hexlet' };
// Creating a function that is immediately assigned to the getName property and becomes a method
company.getName = function() { 
  return 'Hexlet';
};

// Method call
company.getName(); // "Hexlet"

This is just one of the many possible ways to add a function to an object. Below are a few more examples:

// When an object is created
const obj = {
  getName: function() {
    return 'Hexlet'
  },
};

// Via assignment to constant
const company = { name: 'Hexlet' };

function getHexlet() { 
  return 'Hexlet';
};
// The name isn't important
company.getName = getHexlet; 

company.getName(); // "Hexlet"

All of the options above are equivalent. They lead to the same result, but there is one catch. The method returns a string and does not use object data in any way. If the name is changed, the method will continue to return the value stored in it rather than the current name of the company within the object.

company.getName(); // "Hexlet"
company.name = 'Hexlet Plus';
// The name has been changed, but obviously, what it returns remains the same
company.getName(); // "Hexlet"

To solve this problem, we need to access the object data inside the method. This is done through a special keyword called this denoting context. It refers to the current object to which the method is associated.

const company = { name: 'Hexlet', employees: [] };
company.getName = function getName() {
  return this.name;
};

company.getName(); // "Hexlet"
company.name = 'Hexlet Plus';
company.getName(); // "Hexlet Plus"

this makes it possible not only to read the data, but also to change it:

company.setName = function setName(name) {
  this.name = name;
};

company.getName(); // "Hexlet"
company.setName('Hexlet Plus');
company.getName(); // "Hexlet Plus"

Another example, with a change to the internal array in the object:

// Adding a new employee
company.addEmployee = function addEmployee(user) {
  // It's important for the employees to have already been added to the company at the time of the call
  this.employees.push(user);
};

const user = { name: 'Peter' };
company.addEmployee(user);
company.employees; // [{ name: 'Peter' }]

// Or via the method

company.getEmployees = function() {
  return this.employees;
};

company.getEmployees(); // [{ name: 'Peter' }]

As you can see from the examples above, properties can be changed either directly or from methods. Which way to go depends on the situation. With further courses and experience, you'll start to understand better which way to prefer.

Context

Earlier, when the definition of this, was given, it was said that this refers to the current object, to which the method is bound to. And this is where the key difference between this in JavaScript and this in other languages lies. In JavaScript, a method this can change:

const company1 = { name: 'Hexlet', getName: function getName() { return this.name } };
const company2 = { name: 'Hexlet Plus' };

company1.getName(); // "Hexlet"

company2.getName = company1.getName;

// In both cases it's the same function
company2.getName(); // "Hexlet Plus"
company1.getName(); // "Hexlet"

What's happened here? Calling the same function from another object changed the object referenced by this. This feature is called late binding. The value of this refers to the object from which the method is called.

Looking at how JavaScript functions are called and where this comes from can help you comprehend this feature the best. . comes from. Since JavaScript functions are also objects, they have their own methods. Among them is the call(), method, which is used to, as you might expect, call:

const sayHi = () => 'Hi!';
sayHi.call(); // "Hi!"

Why is it done that way? The point is that the first parameter of this function takes a context, an object that will be referenced by this inside the function. Functions don't have to be a method to do this:

const getName = function getName() {
  return this.name;
};

const company1 = { name: 'Hexlet' };
// The function is called directly, it's not a method
getName.call(company1); // "Hexlet"

const company2 = { name: 'Hexlet Plus' };
getName.call(company2); // "Hexlet Plus"

That's the whole secret of this. This is the context that JavaScript throws automatically to a function if it's called as a method. In this case, you can tell exactly which object it belongs to.

Now that you know how this, works, try to answer this question: what will be displayed on the screen?

const company = {
  name: 'Hexlet',
  country: {
    name: 'Finland',
    getName: function getName() {
      return this.name;
    }
  },
};

console.log(company.country.getName()); // => ?

The correct answer is "Finland". Why? Because the context for the getName() method is a country, not a company object. If you modify the code a little bit, it will be easier to understand this idea:

const { country } = company;
console.log(country.getName()); // "Finland"

An shorthand method definition

Because of the need to use normal functions when creating objects, JavaScript has introduced a special abbreviated syntax for creating methods when defining objects:

const company = {
  name: 'Hexlet',
  getName() {
    return this.name;
  },
  // Same as
  // getName: function getName() {
  //   return this.name;
  // },
};

This way is just “syntactic sugar”. It allows you to shorten the notation, but it has no effect on the behavior. The main thing to remember is that this is a regular function, not an arrow function. This is the definition we will use from now on.


Recommended materials

  1. First-class objects

Are there any more questions? Ask them in the Discussion section.

The Hexlet support team or other students will answer you.

About Hexlet learning process

For full access to the course you need a professional subscription.

A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.

Get access
130
courses
1000
exercises
2000+
hours of theory
3200
tests

Sign up

Programming courses for beginners and experienced developers. Start training for free

  • 130 courses, 2000+ hours of theory
  • 1000 practical tasks in a browser
  • 360 000 students
By sending this form, you agree to our Personal Policy and Service Conditions

Our graduates work in companies:

<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.bookmate">Bookmate</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.healthsamurai">Healthsamurai</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.dualboot">Dualboot</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.abbyy">Abbyy</span>
Suggested learning programs
profession
Development of front-end components for web applications
10 months
from scratch
Start at any time

Use Hexlet to the fullest extent!

  • Ask questions about the lesson
  • Test your knowledge in quizzes
  • Practice in your browser
  • Track your progress

Sign up or sign in

By sending this form, you agree to our Personal Policy and Service Conditions
Toto Image

Ask questions if you want to discuss a theory or an exercise. Hexlet Support Team and experienced community members can help find answers and solve a problem.