Inside a nested object, how to get this to refer to the main object?

I have the following code:

const page = {
      elements: {
    //
    heading(value) {
        return this.headings[`${value}`]()
              },
    //   
    },
   init() {

   array.forEach(value => {
       const heading = elements.heading(value);
    })
  }
}

Is there a way that I can make this inside elements.heading to refer to page object? I tried get heading but then this only refers to the elements object, Is there a way I can use the getter to refer to the page object.

Yeah the trick is to use the bind() method of functions. You can put this in your init()…

// Bind your heading function to 'this' (the page object at this point in time to your init method) 
// and assign it back to the function. Now heading function will use this as the page object.
this.elements.heading = this.elements.heading.bind(this); 

I hope this helps. For more information, look up the bind() method for binding different object reference for this.

:slight_smile:

2 Likes

Bind is good to know about, but just a thought — couldn’t heading be swapped for a more generic function like say getValue

Something like this

const page = {
  
  headings: {
    a: 1,
    b: 2,
    c: 3
  },

  getValue: (obj, value) => obj[`${value}`],

  elements: {

  },

  init(arr) {
    arr.forEach(value => {
      console.log(
        // instead of calling heading use getValue passing in the headings obj?
        this.getValue(this.headings, value)
      )
    })
  }
}

page.init(['a','b','c']) // 1, 2, 3

Here is the complete related code, I didn’t add all this at the start because I thought it would be cluttered. my mistake

const page = {
  itemArray: ['pizza', 'curry', 'burger'],
  elements: {
    item: document.createElement('div'),
    image: document.createElement('img'),
    heading(value) {
      return this.headings[`${value}`]();
    },
    para: document.createElement('p'),
    hr: document.createElement('hr'),
  },
  headings: {
    pizza: function () {
      const tempHeading = document.createElement('h2');
      tempHeading.innerText = 'Italian Pizza';
      return tempHeading;
    },
    curry: function () {
      const tempHeading = document.createElement('h2');
      tempHeading.innerText = 'Chicken Curry';
      return tempHeading;
    },
    burger: function () {
      const tempHeading = document.createElement('h2');
      tempHeading.innerText = 'Mushroom Burger';
      return tempHeading;
    },
  },
  init() {
    this.itemArray.forEach((value) => {
      const heading = this.elements.heading(value);
    });
  },
};

This worked, but I ran into a new problem. anyways, Thank you for the help!

You could just call this.headings directly and remove the method from elements. Saves going around the houses.

  init(foodItems) {
    foodItems.forEach((foodType) => {
        const heading = this.headings[foodType]()
        ...
    })
}
1 Like

Before this, I was doing that where all of the items in elements were variables in the forEach function, but I wanted them to all be in a object of their own, so that things were cleaner and I wanted to create a method which allowed new elements to be inserted in the object.

I might have to go back to that anyways.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.