This keyword in JavaScript | JS, TS, React and Angular Forum
Y
Yogesh Chawla Posted on 25/12/2022

Question:

Hi Yogesh,

Could you please tell me why I am seeing that "undefined" in the output?
class Animal {
    static planet = 'Earth';

    constructor(name, speed = 10) {
        this.name = name;
        this.speed = speed;
    }

    static compareSpeeds(a1, a2) {
        return a2.speed - a1.speed;
    }

    run() {
        console.log(`${this.name} runs at ${this.speed} mph`);
    }

    eat() {
        console.log(`${this.name} eats like an animal`);
    }

    describe() {
        this.eat();
        this.run();
    }

}

class Tiger extends Animal {

    constructor(name, speed, foodType) {
        super(name, speed);
        this.foodType = foodType;
    }

    eat() {
        console.log(`${this.name} eats ${this.foodType}`);
    }


}

class Elephant extends Animal {

    constructor(name, speed, foodType) {
        super(name, speed);
        this.foodType = foodType;
    }

    eat() {
        console.log(`${this.name} eats ${this.foodType}`);
    }


}

let arrayOfAnimals = [new Animal("generic animal"), 
new Animal("fast generic animal", 20), 
new Elephant("elephant", 5, "herbivorous food"), 
new Tiger("tiger", 90, "meat")];
arrayOfAnimals.sort(Animal.compareSpeeds);//sort from fastest to slowest
// arrayOfAnimals.forEach((a) => console.log('In ', Animal.planet, a.describe()));
for(var a of arrayOfAnimals) {
    console.log(Animal.planet);
    console.log(a.describe());
} 

OUTPUT 
Earth
tiger eats meat
tiger runs at 90 mph
undefined
Earth
fast generic animal eats like an animal
fast generic animal runs at 20 mph
undefined
Earth
generic animal eats like an animal
generic animal runs at 10 mph
undefined
Earth
elephant eats herbivorous food
elephant runs at 5 mph
undefined

Also, could you show how I can debug code in vscode when we meet next?

Thanks,
Vijay

Y
Yogesh Chawla Replied on 25/12/2022

1. "this" keyword refers to the object which invoked the method 
when referenced inside a method. 
- This one is pretty simple, this is how this keyword works in every language.

2. "this" keyword refers to the global object when used inside a function, 
but is undefined when invoked in function in strict mode.
-- There is "use strict" statement that we write on top of a script which means, 
before this

According to ES6 classes, strict mode is always enabled and cannot be disabled.
It's a new feature of ECMAScript 5. 

It's just a string you put in your JavaScript files (either at the top of your file or inside of a function) that looks like this:

"use strict";

Putting it in your code now shouldn't cause any problems with current browsers as it's just a string. It may cause problems with your code in the future if your code violates the pragma. For instance, if you currently have foo = "bar" without defining foo first, your code will start failing...

In your case, this is the class:

class Animal {
    static planet = 'Earth';

    constructor(name, speed = 10) {
        this.name = name;
        this.speed = speed;
    }

    static compareSpeeds(a1, a2) {
        return a2.speed - a1.speed;
    }

    run() {
        console.log(`${this.name} runs at ${this.speed} mph`);
    }

    eat() {
        console.log(`${this.name} eats like an animal`);
    }

    describe() {
        this.eat();
        this.run();
    }
   
}

//this is the array of objects of above class
let arrayOfAnimals = [new Animal("generic animal", 10),
new Animal("fast generic animal", 20)];
arrayOfAnimals.sort(Animal.compareSpeeds);//sort from fastest to slowest
// arrayOfAnimals.forEach((a) => console.log('In ', Animal.planet, a.describe()));

//console.log(arrayOfAnimals.sort(Animal.compareSpeeds));
//console.log(arrayOfAnimals.length);

//Now to make this keyword work outside the class, we are using apply method.
//With apply() method, you can write a method that can be used on different objects.



const person = {
  describeOutput: function() { //this is a method inside the object
return this.eat() + " " + this.run();
}
}

for(let a of arrayOfAnimals) {
console.log(Animal.planet);
//console.log(a.describe());
      person.describeOutput.apply(a); //and here i am calling a method with apply on 
      //the object so that this keyword can work properly
}  

3. "this" keyword in Javascript refers to the DOM element when used inside an event fired on the DOM element.