JavaScript This

Dr. Greg Bernstein

Updated April 25th, 2021

this in JavaScript

Learning Objectives

  • Review the purpose of the this keyword
  • Understand how it value is context dependent
  • Learn the values it takes in different contexts
  • Learn how to set its value with apply, call, and bind methods

Readings

Use of this 1

From The Magic Of this Keyword:

“JavaScript borrows this keyword from C++, where it is used to point to an instance of an object from within its own class definition.”

this Example

Referencing object members from a method (member function)

// An object with methods
var mySession = {
  name: "Dr. B",
  wind: 22,
  sail: 6.6,
  description() {
    return `${this.name} sailed on a ${this.sail} in ${this.wind}mph of wind`;
  }
};

Use of this 2

From The Magic Of this Keyword:

“The original designer of JavaScript decided to tie a secondary feature to this keyword. Not only is it used to point to an instance of an object from its own constructor or its methods (hence, this) it is also used to keep track of execution context — which is often based on where a function was called from.”

Take Away 1

From The Magic Of this Keyword:

“This duality of the this keyword is exactly what has wrecked havoc on learning and understanding how it works. It is also why this keyword can be so confusing even to programmers who come to JavaScript from C++.”

Function this

From MDN:

A function’s this keyword behaves a little differently in JavaScript compared to other languages.

In most cases, the value of this is determined by how a function is called. It can’t be set by assignment during execution, and it may be different each time the function is called.

Global context

From MDN:

In the global execution context (outside of any function), this refers to the global object, whether in strict mode or not.

Try the following in your browser console:

console.log(this); //this points to the window object.

General Function Context

From “understanding this”

// define a function
var myFunction = function () {
  console.log(this); // [object Window]
};

// call it
myFunction();

Object Literal

Explanded from “understanding this”

// create an object
var myObject = {name: "My thing"};
var myObj2 = {name: "Other thing"};

// create a method on our object
myObject.someMethod = function () {
  console.log(this);
};

// call our method
myObject.someMethod();
// Assign method to a variable
var myFunc = myObject.someMethod; // Assigning a function!
myFunc(); // Call it
// Assign method to another object
myObj2.aMethod = myObject.someMethod;
myObj2.aMethod(); // call it

Events

From “understanding this”

click target

// let's assume .elem is <div class="elem"></div>
var element = document.querySelector('.MyElem');
var someMethod = function () {
  console.log(this);
};
element.addEventListener('click', someMethod, false);

Arrow Functions

From MDN: Arrow functions capture the this value of the enclosing context, so the following code works as expected.

function Person(name="") {
    this.name = name
    this.age = 0;
    this.timer = setInterval(() => {
      this.age++; // |this| properly refers to the person object
      console.log(this.name + " is " + this.age + " old");
      if(this.age > 30) { // Old enough!
        clearInterval(this.timer);
      }
  }, 1000);
}

var p = new Person();

Changing this

From “understanding this”:“Functions are first class Objects,” which means that they can also have their own methods! See MDN Function

  • .call(thisArg[, arg1, arg2, ...]); — calls the function too.
  • .apply(thisArg[, argsArray]); — calls the function too.
  • .bind(thisArg[, arg1[, arg2[, ...]]]) — does not call the function!

Example

var myObj = {course: "CS351", slogan: "Code the web!"};
function myFunction() {
    console.log(this);
}
myFunction();
myFunction.apply(myObj);
myFunction.call(myObj);
var newFunc = myFunction.bind(myObj);
newFunc();

Usage Scenario

The bind() approach is particularly well suited to assigning this to a function that will be passed as a callback. In this case we do not want to evaluate the function just bind a specific object to this.

Another alternative could be an arrow function.

// reveal.js plugins