Skip to content

Instantly share code, notes, and snippets.

@ross-u
Last active February 8, 2021 07:39
Show Gist options
  • Save ross-u/80222d9e69cf4d792d34d56071758efd to your computer and use it in GitHub Desktop.
Save ross-u/80222d9e69cf4d792d34d56071758efd to your computer and use it in GitHub Desktop.
Lecture - JS | Special value this (Teacher Notes)

Teacher Notes:

JS | Special keyword this


Create folder/file structure for the examples

mkdir js-this && cd js-this
mkdir src

touch src/index.js index.html

code .

Intro

In this lecture we will talk special value this and explain 5 rules it has.


What is this and where is it used ?

this is a special keyword value that JavaScript automatically creates in the scope of every function.

Once a function is called and it executes, this is created inside of the scope of that function.

It is a misconception that this is used in the objects. Wrong!

In JavaScript this is used in the funcitons and it's sole purpose is to be used in the functions to enable the reusability of the function.


Why understanding this is important ?

this is one of the most misunderstood mechanisms in Javascript. Many JavaScript developers don't fully understand how this works and why it is even used.

However, this mechanism has few simple rules that we will learn in the following steps.

Understanding this special keyword value is an important foundational concept used in many areas of JavaScript.

After learning how this works in JavaScript you will be able to:

  • Use this effectively in functions and arrow functions
  • Use functions properly as methods in OOP.
  • Be able to answer common interview question when asked about this and solve related interview challenges.
  • Successfully handle callbacks of DOM event listeners, setTimeout and setInterval .
  • Better understand code of other developers such as one found in libraries, packages, frameworks.

❓ Knowledge check >

A common interview question for junior developers is, that I would like you to answer now in our slack channel:

Q:

Where is `this` always used in JavaScript ?

A:

`this` is always used in functions.

These are the 5 rules that describe how the value of this is used in JavaScript:


1. Using keyword new in class

If the new keyword is used when calling the class or a function, this inside the function is a brand new object.

function Car (brand, model) {
	console.log(this); // ==> {}
}


new Car();  //	{}

What happens behind the scene is that value this holds the new empty object instantiated by the class to which the properties are added. At the end constructor returns the newly created object.

function Car (brand, model) {
	// this = {}
  console.log(this);
  
  this.brand = brand;
  this.model = model;
  
  console.log(this);  // this = { brand: '...',  model: ''}
  
  // return this
}

const carObj = new Car();

2. In a standalone function invocation this

If a function is being invoked as a standalone funciton (without an object on the left side), then this inside of that function refers to the global object Window (or undefined if in strict mode).

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

whatIsThis();

3. this in function methods

this keyword in the method holds the value of whatever is on the left of the dot at the time of invocation (the object that is invoking the method).

Question

const person1 = {
  name: 'John',
  age: 30,
  printThis: function () {
    console.log('one', this);
  },
  address: {
    country: 'Scotland',
    city: 'Glasgow',
    printThis: function () {
      console.log('two', this);
    },
  }
};
// What is this in the `person.printThis` ?
person1.printThis();


// What is this in the `person.address.printThis` ?
person1.address.printThis();

4. Exception - this in arrow functions

If the function/method is an ES2015 arrow function, it receives this value of its surrounding scope at the time it is created.

const person2 = {
  name: 'Alberto',
  age: 41,
  
  regularMethod: function () {
    console.log('regularMethod  this', this)
    
    const arrowFunc = () => console.log('arrowFunc  this', this);
    arrowFunc();
    
    // arrow function will borrow `this` value from the surrounding scope
    // of `regularMethod` where it was created
  },
  
};


person.regularMethod();

Using arrow function to prevent loss of this

Certain built-in JavaScript functions and interfaces cause the loss of this value in the functions.

These are setTimeout/setInterval, event listeners and loop methods forEach/map/filter.

class Clock {
  constructor() {
    this.time = 0;
      
    this.tickRegular = function () {  
      this.time += 1;
      console.log(this.time);
    };
    
  }
};

const clockA = new Clock();

setInterval( clockA.tickRegular, 1000 ); //

In the above example setInterval is continuously invoking the method tickRegular every 1s ( 1000 milliseconds ). However the this value in the tickRegular is lost as method is called as a callback by the browser's function setInterval.

One common technique to prevent the loss of this in when using the above mentioned built-in functions is to use arrow functions or arrow methods. Let's see how we can fix the above problem by using an arrow method instead:


class BetterClock {
  constructor() {
    this.time = 0;
    
    this.tickArrow = () => {
      this.time += 1;
      console.log(this.time);
    }
    
  }
};

const clockB = new BetterClock();

setInterval( clockB.tickRegular, 1000 ); //

We can see that arrow function takes the value of this from the scope in which it was created, from the constructor, where this represents the new object instance.


5. Using call() , apply() or bind()

Methods call(), apply() or bind() can explicity set the value of this inside of a function.

These methods can only be used with regular funciton and can not be used for arrow funcitons.


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


const office = {
  address: 'C. Pamplona 96',
  color: 'gray'
}

const school = {
  address: '120 SW 8th St',
  color: 'white'
}


printThis(); // --> Window

printThis.call(office); //  -->  office { address: "C. Pamplona 96", color: "gray" }

printThis.call(office); //  -->  school { address: "120 SW 8th St", color: "white" }

bind()

bind() method is used to create a new function with a permanently set (bound) this value.

Method bind() creates a copy out of an existing function and sets this to the provided value.

const car = {
  brand: 'Tesla',
  model: 'S',
  details: function () {
    console.log(`${this.brand} ${this.model}`);
  }
}

car.details(); // -->   Tesla S



const macPro15 = {
  brand: 'Apple',
  model: 'MacBook Pro 15'
}


// Create a new function and bind `this` to object `macPro15`
const boundDetails = car.details.bind(macPro15);


boundDetails(); // --> Apple MacBook Pro 15
boundDetails(); // --> Apple MacBook Pro 15


// new function `boundDetails` has `this`
// permanently bound to object `macPro15`

❓ Knowledge check >

Let's take 5 minutes to recall 5 rules of this and how the value changes. Let's all write them down in Slack and then when ready post your answer in the general channel. To begin with I will provide you with the first rule:

**Q:**
What are 5 rules where this in a function changes ? 

1. In `class` when using keyword `new`... the value of `this` is the new object instance.
2. In a standalone function, the value of `this` is...

A:

2. In a standalone function, the value of `this` is the global object (Window)
3. In function methods, the value of `this` is object on the left of the dot at the time of inovcation

4. Arrow functions don't have `this` binding, but they borrow `this` from the scope in which they are created.
5. Using call(), apply() or bind() we can change the value of `this` in a function.

Conclusion and Summary

  • Calling a function without a leading parent object will get you the value of this as the global/window

  • In a method function which is a method, this points to whatever is -> On the left of the dot at the time of invocation (calling the function).

  • When using keyword new with a constructor, this represents a newly created object.

  • Arrow functions do not bind it's own this, but they take this from the surrounding scope where they were created.

  • We use call , apply or bind to change thethis value of a function.


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment