简体   繁体   中英

How to recursively iterate over a JS object, while creating a new object, with a similar structure?

I'm trying to create a "composition" of objects, where each object will have some properties, and references to other objects(let's regard them as "children");

This composite structure is created from a config object, that lays out the structure. For example:

const configObj = {

    baseSiteUrl: `https://example.com`,
    startUrl: `https://example.com/products`,
    type:'root',
    children: [
        {
            type: 'link',
            name: '.product_name_link',
            children: [
                {
                    type: 'data',
                    name: '.product_publisher'
                }

            ]
        }
    ]

}

I need to translate such a structure to an actual composition of object instances(I have "Link" and "Data" classes, each of which serves a different purpose: Link sends an HTTP request to that address, Data fetches a certain element).

What i have tried so far, is a pure ridiculous hack. This is my recursive function:

function createObjectsFromTree(object) {
    const classReference = getClassMap()[object.type];//Brings a reference to the appropriate class.

    if(object.type !== 'root'){
        object.actualObject = new classReference(object.name, object.children || null);//This is the hack: it just creates a property called "actualObject", on the original object. 
    }       

    if (!object.children) {
        return;
    }

    object.children.forEach((child) => {        

        createObjectsFromTree(child)
    })

}

 createObjectsFromTree(configObj);//Making the initial call

This is the getClassMap function:

 function getClassMap() {
    return {
        link: Link,
        root:Root,
        data: Data
    }

}

As you can see, i'm just modifying the original config object, adding an "actualObject" property, which holds an instance to an object, and this process repeats it self.

This is obviously totally flawed, and will only cause problems, and make my code unmaintainable.

How could i create a fresh composition of objects, according to the config "blueprint"?

The new object should look something like that, in the console:

{

    baseSiteUrl: `https://example.com`,
    startUrl: `https://example.com/products`,
    type:'root',
    children: [
        Link{// "Link" is the class name                
            name: '.product_name_link',
            children: [
                Data{// "Data" is the class name                         
                    name: '.product_publisher'
                }

            ]
        }
    ]

}

Any idea would be greatly appreciated!

I attempted to make it as short as possible. I assume you wanted to achieve something like that:

function createObjectsFromTree(object) {
  let Class = getClassMap()[object.type];
  return new Class(
    object.name,
    (object.children || []).map(createObjectsFromTree)
  );
}

Here is a JSFiddle .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM