AndrePaganotto
AndrePaganotto

Reputation: 37

Function inside an Object inside a Class

I have a class and this class have a function. I want to call that function from inside another function that is inside an object inside of that class.

Here is the code:

class Animal
{
    constructor(name)
    {
        this.name = name
    }

    //This is the function i want to call from inside the object below
    emitSound(sound)
    {
        return `I am ${sound}`
    }

    //This is the object with functions
    actions = {
        eat()
        {
            return this.emitSound('eating');
        },
        sleep()
        {
            return this.emitSound('sleeping');
        }
    }
}

const animal = new Animal('Dog');

console.log(animal.actions.eat());

(this code is just an example, the application im developing is way more complex)

How you can see, it returns an error saying that "this.emitSound()" is undefined. Its happening because the function eat() is trying to call this from inside the actions object, isnt it?

So what I need is a way to call the emitSound() function inside the actions object functions. Please help!!!

Upvotes: 2

Views: 1253

Answers (1)

Guerric P
Guerric P

Reputation: 31835

That's because this refers to actions because you're calling it as a method of actions: actions.eat().

One workaround is to bind the functions to the current instance in the constructor:

class Animal
{
    constructor(name)
    {
        this.name = name
        this.actions.eat = this.actions.eat.bind(this);
        this.actions.sleep = this.actions.sleep.bind(this);
    }

    //This is the function i want to call from inside the object below
    emitSound(sound)
    {
        return `I am ${sound}`
    }

    //This is the object with functions
    actions = {
        eat()
        {
            return this.emitSound('eating');
        },
        sleep()
        {
            return this.emitSound('sleeping');
        }
    }
}

const animal = new Animal('Dog');

console.log(animal.actions.eat());

Other option: declare the functions as arrow functions:

class Animal
{
    constructor(name)
    {
        this.name = name
    }

    //This is the function i want to call from inside the object below
    emitSound(sound)
    {
        return `I am ${sound}`
    }

    //This is the object with functions
    actions = {
        eat: () => this.emitSound('eating'),
        sleep: () => this.emitSound('sleeping')
    }
}

const animal = new Animal('Dog');

console.log(animal.actions.eat());

Upvotes: 7

Related Questions