I have a question for experts :) I'm trying to make a dynamically generated "decision tree". The data you need is stored in a global variable.

const mainObj = { second: { name: 'second', valueToOutput: "someString", }, third: { name: 'third', valueToOutput: "someString", }, first: { name: 'first', nextEls: [second, third] } } 

When I initialize a variable, I immediately grab the Uncaught ReferenceError: second is not defined error Uncaught ReferenceError: second is not defined , I try to initiate through this

 const mainObj = { second: { name: 'second', valueToOutput: "someString", }, third: { name: 'third', valueToOutput: "someString", }, first: { name: 'first', nextEls: [this.second, this.third] } } 

variable is initiated. But I get such an object at the end

first: { name: 'first', nextEls: [undefined, undefined] }

this is the essence of the problem - is it possible to refer to properties in properties? And if so, how is this better implemented?

    5 answers 5

    It is enough to store the names of the following elements:

     const mainObj = { second: { name: 'second', valueToOutput: "someString", }, third: { name: 'third', valueToOutput: "someString", }, first: { name: 'first', nextEls: ['second', 'third'] } } 

    Appealing to the property itself becomes trivial.

      It’s better not to hardcode anything right away. Create an empty object, then fill it in successively:

       const mainObj = {}; mainObj.second = { name: 'second', valueToOutput: "someString" } mainObj.third = { name: 'third', valueToOutput: "someString" } mainObj.first = { name: 'first', nextEls: [mainObj.second, mainObj.third] } 

        The essence of the problem is that during the creation of the mainObj object and its first subobject (that is, during the execution of the code that returns values ​​for the properties of these objects), these objects do not yet exist.

         function createMainObj() { var result = { second: { name: 'second', valueToOutput: "someString", }, third: { name: 'third', valueToOutput: "someString", }, first: { name: 'first', nextEls: [] } }; result.first.nextEls.push(result.second); result.first.nextEls.push(result.third); return result; } const mainObj = createMainObj(); console.log(mainObj.first); 

        • This is a good option when you have few elements, but when there are about 1000, it is already problematic to determine which way to push and not to get confused. Otherwise nothing at all? - Diana Meissen
        • @DianaMeissen In another way - no way. The degree of complexity here is exactly the same as in your code. - Igor
        • understood, thanks - Diana Meissen

        You can use getters together with this , since this is only relevant for calling methods, not properties. But in getters, this method will have access only to the same level of nesting (in your example, this would refer to the mainObj.first object, if it were possible):

         const mainObj = { second: 2, third: 3, get others() { return [this.second, this.third]; } } console.log(mainObj.others); 
         [ 2, 3 ] 

          It is better to just break into two steps:

           const mainObj = { second: { name: 'second', valueToOutput: "someString", }, third: { name: 'third', valueToOutput: "someString", }, } mainObj.first = { name: 'first', nextEls: [mainObj.second, mainObj.third] } 

          this better not to use this, since in nested arrays / objects the context is simply lost. In general, for such cases it is better to use classes with a constructor: https://learn.javascript.ru/es-class