DEV Community

Cover image for I can help with 'this' Confusion
Stephen Odogwu
Stephen Odogwu

Posted on • Updated on

I can help with 'this' Confusion

First, let us go back to the roots, the English meaning of the word 'this'. According to the Oxford dictionary, this can be used to identify a specific person or thing close at hand, it can also be used to identify something. For example "this is Stephen talking". The word can also be used to compare the distance between two things, the nearer one referred to as this and the farther one referred to as that.

Prerequisites

  • Know the difference between methods and functions.
  • Know what an Object literal is.

Use in JavaScript

Now over the past 14months since I have been using and writing JavaScript, I realized it is used in 4 areas. Below is a list of the areas.

  • Global scope in a browser environment

  • Object Oriented Programming (OOP)

  • Data structures and algorithms(DSA) e.g. Implementation of stacks ,Queues,Binary search Trees.

  • Document Object Model (DOM) manipulation

The Rundown

Below we throw more light on the four listed areas above.

Global Scope

When used in the global Scope, one with a web environment, not a Node.js environment, this points to the global object which is window.

Meaning when we run JavaScript as an HTML attachment, like below.

<html> 

<body>

</body>

<script src="script.js">
</script>
</html>
Enter fullscreen mode Exit fullscreen mode

Such that this points to the window Object.

console.log(this) //window object

console.log(this==window) //true
Enter fullscreen mode Exit fullscreen mode
  • Let us take a look at the behaviour Outside the web environment: Node js*

Such that this points to an empty Object.

console.log(this) //{ }
console.log(this==window) //reference error
Enter fullscreen mode Exit fullscreen mode

Before you get scared!!.
Before we dive into use in code, I am going to list the use cases and places of this in OOP, so that you can know what is obtainable as soon as you see them.

  • this is not used on properties of Object literals. It is only used within the methods of object literals pointing to the properties.

  • it is also not used on the properties of factory functions. It is only used optionally within the methods of factory functions.

  • It is used on properties and methods of constructor functions except when making prototypes.

  • it is used on properties and methods of classes except when making prototypes.

Object Oriented Programming (OOP)

To get a picture of things I just enumerated, let us touch briefly on the methods of creating Objects in OOP JavaScript to visualize it.

Object literal: The this keyword is not used on the properties here. It is only used within the method to point to a property. in this example the greet method, it points to name.

const person = {
  name: 'steve',
  age: 30,
  greet: function () {
    console.log(`Hello, say goodmorning to ${this.name}.`)
  }
}
person.greet(); // logs "Hello,say goodmorning to steve."
Enter fullscreen mode Exit fullscreen mode

Factory Functions: The this keyword is only used within the method definition in factory functions. In this case getFrom() to refer to the from property. But it is not used on the properties, from and to.

function way(from,to){
return{
from:from,
to:to,
getFrom:function(){
console.log(this.from)
}
}
}
//Instantiate
const route=way("Lagos","Toronto")
route.getFrom()
Enter fullscreen mode Exit fullscreen mode

Mind you, you can also rewrite the above as 👇

function way(from,to){
return{
from,
to,
getFrom:function(){
console.log(this.from)
}
}
}
//Instantiate
const route=way("Lagos","Toronto")
route.getFrom()
Enter fullscreen mode Exit fullscreen mode

Or no need to add this within the method getFrom().

function way(from,to){
return{
from:from,
to:to,
getFrom:function(){
console.log(from)
}
}
}
//Instantiate
const route=way("Lagos","Toronto")
route.getFrom()
Enter fullscreen mode Exit fullscreen mode

Constructor Functions: One of the confusions people face, is not knowing the difference between constructor and factory functions, and that is a major confusion as far as this keyword goes. By convention, constructor function names start with uppercase letters (capital letters), and we use the this keyword to enumerate their properties. We also instantiate with the new keyword which we don't do in factory functions. Note that the constructor is a template which we use to build our objects.

function Way(from,to){
    this.from=from
     this.to=to
    this.get=function(){
        return this.from
    }
}
//instantiate
const route=new Way("Lagos","London")
console.log(route.from)
console.log(route.to)
console.log(route.get())
Enter fullscreen mode Exit fullscreen mode

Class and Class Constructor: Follows the same principle as the constructor function, except some syntax modification which some call syntactic coating. We use the new keyword to instantiate too. Notice the difference that a class is used to encapsulate constructor.

class Lecturer{
    constructor(name,degree){
        this.name=name
        this.degree=degree    
}
}

//instances of class
let person1=new Lecturer("Jim","PhD")
let person2=new Lecturer("Kennedy","phD")
console.log(person1)
console.log(person2)
Enter fullscreen mode Exit fullscreen mode

DSA

The use in DSA follows the class and class constructor syntax talked about above. Below is the blueprint to implement a stack with an array using the class syntax.

class Stack {
        constructor() {
            this.items = [];
            this.top = -1;
        }
    }
Enter fullscreen mode Exit fullscreen mode

DOM manipulation

I have also seen some DOM manipulation with OOP using the DOM. It also employs the class syntax in this scenario.Below is an example I saw.

 class Button {
  constructor(text,color,clickr) {
    this.element = document.createElement("button");
    this.element.innerText = text;
    this.element.style.color=color
    this.element.addEventListener("click",clickr);
  }
  //prototype zone

  appendTo=function (parent) {
    parent.appendChild(this.element);
  }
}

//  instantiate Button class
var myButton = new Button("Click me!","red", function() {
  alert("Button was clicked!");
});
// Append the button to the DOM myButton.appendTo(document.body);
Enter fullscreen mode Exit fullscreen mode

Behaviour Within Regular Functions

Regular functions are functions not attached to any object. It will always take the value of the owner of the function in which it is used. Within functions it usually points to the window object, if in strict mode it reads undefined.

function greet(){
console.log('Good Morning')
console.log(this)
}
greet()
//outputs Good Morning and window
Enter fullscreen mode Exit fullscreen mode

In strict mode

'use strict'

function greet(){
console.log('Good Morning')
console.log(this)
}
greet()
//outputs Good Morning and undefined
Enter fullscreen mode Exit fullscreen mode

Arrow functions

When used within Arrow functions, this points to the parent scope of the function they are used in.

let x=()=>{

console.log(this)

}

x()
Enter fullscreen mode Exit fullscreen mode

//outputs window since the parent of the function is the global scope

Recommendation

To gain more clarity on all I touched on, to brush up your OOP knowledge. Check the Procademy YouTube channel, he has a series on object oriented programming in JavaScript. Follow it chronologically, he breaks every concept down. Even a toddler would understand. Don't be scared to drop a question, correction or comment.

Top comments (0)