How to restore original object/type from JSON?

前端 未结 6 1697
旧时难觅i
旧时难觅i 2020-12-05 19:38

Its easy to load JSON into an object in javascript using eval or JSON.parse.

But if you have a proper \"class\" like function, how do you get the JSON data into it?<

6条回答
  •  北荒
    北荒 (楼主)
    2020-12-05 20:02

    A little late to the party, but this might help someone. This is how I've solved it, ES6 syntax:

    class Page 
    {
       constructor() {
          this.__className = "Page";
       }
    
       __initialize() {
           // Do whatever initialization you need here.
           // We'll use this as a makeshift constructor.
           // This method is NOT required, though
       }
    }
    
    class PageSection
    {
       constructor() {
          this.__className = "PageSection";
       }
    }
    
    class ObjectRebuilder
    {
        // We need this so we can instantiate objects from class name strings
        static classList() {
            return {
                Page: Page,
                PageSection: PageSection
            }
        }
    
        // Checks if passed variable is object.
        // Returns true for arrays as well, as intended
        static isObject(varOrObj) {
            return varOrObj !== null && typeof varOrObj === 'object';
        }
    
        static restoreObject(obj) {
            let newObj = obj;
    
            // At this point we have regular javascript object
            // which we got from JSON.parse. First, check if it
            // has "__className" property which we defined in the
            // constructor of each class
            if (obj.hasOwnProperty("__className")) {
                let list = ObjectRebuilder.classList();
    
                // Instantiate object of the correct class
                newObj = new (list[obj["__className"]]);
    
                // Copy all of current object's properties
                // to the newly instantiated object
                newObj = Object.assign(newObj, obj);
    
                // Run the makeshift constructor, if the
                // new object has one
                if (newObj.__initialize === 'function') {
                    newObj.__initialize();
                }
            }
    
            // Iterate over all of the properties of the new
            // object, and if some of them are objects (or arrays!) 
            // constructed by JSON.parse, run them through ObjectRebuilder
            for (let prop of Object.keys(newObj)) {
                if (ObjectRebuilder.isObject(newObj[prop])) {
                    newObj[prop] = ObjectRebuilder.restoreObject(newObj[prop]);
                }
            }
    
            return newObj;
        }
    }
    
    let page = new Page();
    let section1 = new PageSection();
    let section2 = new PageSection();
    
    page.pageSections = [section1, section2];
    
    let jsonString = JSON.stringify(page);
    let restoredPageWithPageSections = ObjectRebuilder.restoreObject(JSON.parse(jsonString));
    
    console.log(restoredPageWithPageSections);
    

    Your page should be restored as an object of class Page, with array containing 2 objects of class PageSection. Recursion works all the way to the last object regardless of depth.

    @Sean Kinsey's answer helped me get to my solution.

提交回复
热议问题