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
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);
}