recursive JSON.stringify implementation

后端 未结 6 1816
被撕碎了的回忆
被撕碎了的回忆 2021-02-04 21:25

I am trying to learn recursion in Javascript, so I figured I\'d rewrite the native JSON.stringify function using recursion as a challenge to myself. I almost got my

6条回答
  •  佛祖请我去吃肉
    2021-02-04 21:59

    You need to view recursion as going deeper into the object without actually altering the object. It looks like you're trying to use recursion to go sideways inside of an object.

    I've written a version of stringify that handles basic object (no arrays or functions).

    Here is the fiddle

    Here is the code:

    var my_stringify2 = function (obj) {
        var objKeys = Object.keys(obj);
        var keyValueArray = new Array();
        for (var i = 0; i < objKeys.length; i++) {
            var keyValueString = '"' + objKeys[i] + '":';
            var objValue = obj[objKeys[i]];
            keyValueString = (typeof objValue == "string") ? 
                keyValueString = keyValueString + '"' + objValue + '"' : 
                keyValueString = keyValueString + my_stringify2(objValue);
            keyValueArray.push(keyValueString);
        }
        return "{" + keyValueArray.join(",") + "}";
    }
    

    You want the recursion to do most of the work for you, and you should only need to handle basic conditions (which you already had). In my function the two acceptable conditions are string and object.

    A string is handled on the spot, and an object is passed into the function recursively.

    That's the key. You were passing the same object into the function repeatedly, removing the handled elements until you get to a point where the object is completely gone.

    What I did instead was pass the value of that particular property if it were an object. If it's a string, just add it to the string and move along.

    Take a look at the code and let me know if you have any questions. Notice that the object that I'm passing in has a nested object.

    my_stringify2({
        foo: 'bar',
        bar: 'foo',
        foobar: {
            foo: 'bar',
            bar: 'foo'
        }
    });
    

    and the result is proper json

    {"foo":"bar","bar":"foo","foobar":{"foo":"bar","bar":"foo"}} 
    

    If you're looking to completely avoid a for loop, you can do the following

    jsfiddle

    in this one you pass the object like normal, but recursively you pass a key array, removing an element from the key array for each property.

    a bit more complicated, so I added comments

    var my_stringify2 = function (obj, objKeys) {
        var str = "";
        // keys haven't been loaded, either first pass, or processing a value of type object
        if (objKeys == undefined) { 
            objKeys = Object.keys(obj);
            str = "{"
        } else {
            // if keys array exists and is empty, no more properties to evaluate, return the end bracket
            if (objKeys.length == 0) {
                return "}";
            // array exists and isn't empty, that means it's a property and not the first property, add a comma    
            } else {
                str = ",";
            }
        }
        // add the property name
        str += '"' + objKeys[0] + '":';
        // get the value
        var objValue = obj[objKeys[0]];
        // if the value type is string, add the string, if it's an object, call this function again, but leave the objKeys undefined
        str +=
            (typeof objValue == "string") ? 
            '"' + objValue + '"' : 
             my_stringify2(objValue);    
        // remove the first element fromt the keys array
        objKeys.splice(0,1);
        //call the function for the next property
        return str + my_stringify2(obj, objKeys);
    }
    

提交回复
热议问题