Search code examples
javascriptjavascript-objects

Why is class instance method resulting in undefined after invocation. Is Timeout function correct?


aeri.attack / aeri.magicAttack results in the attack() function. But if I try to invoke the function it results in undefined. WHY.

I tried doing a Character instance to see if it was just the subclass but it's not.

PS if someone could tell me if im doing the setTimeout function right that would be awesome and I would love you forever.

PS PS I can't test if the timeout method is working because NONE of my methods are working.

class Character {
    constructor(name, weapon) {
        this.name = name;
        this.weapon = weapon;
    }

    attack(){
        this.name + ' attacks with ' + this.weapon;
    }
}

class Elf extends Character {
    constructor(name, weapon, type) {
        super(name, weapon);
        this.type = type;
    }

    magicAttack() {
        this.name + ' chants ';
        setTimeout(function(){this.type; }, 3000);


    }
}

const aeri = new Elf("Aeri", "bow", "air")
const bob = new Character("Bob", "yawn")

Solution

  • There's a couple of reasons why the code from the original post doesn't do what the OP is expecting it to do.

    class Character {
        constructor(name, weapon) {
            this.name = name;
            this.weapon = weapon;
        }
    
        attack(){
            this.name + ' attacks with ' + this.weapon;  //  (1)
        }
    }
    
    class Elf extends Character {
        constructor(name, weapon, type) {
            super(name, weapon);
            this.type = type;
        }
    
        magicAttack() {
            this.name + ' chants ';                      //  (2)
            setTimeout(function(){this.type; }, 3000);   //  (3)
    
    
        }
    }
    
    const aeri = new Elf("Aeri", "bow", "air")
    const bob = new Character("Bob", "yawn")
    

    (1) The attack() method is missing a return statement

    (2) The this.name + ' chants '; statement is not doing anything since the result of the concatenation is not assigned to a variable or passed to a method, so it's simply discarded.

    (3) The anonymous function passed to setTimeout references this.type, but given how this works in JavaScript, the type is undefined in this context (because this is actually the anonymous function itself).

    To see the results of calling the method, the following changes would need to be applied to the original code sample:

    class Character {
        constructor(name, weapon) {
            this.name = name;
            this.weapon = weapon;
        }
    
        attack(){
            return this.name + ' attacks with ' + this.weapon;    //  (1)
        }
    }
    
    class Elf extends Character {
        constructor(name, weapon, type) {
            super(name, weapon);
            this.type = type;
        }
    
        magicAttack() {
            const chant = this.name + ' chants ';                  //  (2)
            setTimeout(function(){ console.log(chant); }, 3000);   //  (3)
    
        }
    }
    
    const aeri = new Elf("Aeri", "bow", "air")
    const bob = new Character("Bob", "yawn")
    
    aeri.magickAttack();
    

    Hope this helps!

    Jan