Create your own JSON.stringify() function

by Matt Heff

If you have been around the traps the JavaScript for a while you will know JSON.stringify(), you may have have even used it to compare objects, make clones of objects and arrays or even work with RESTful API’s. Using it is not enough of people like you and me, we must pull it apart, look under the hood and then make our own version of it.

This is a two way operation JSON.stringify() will turn objects into strings the inverse of that is JSON.parse() which will objectify strings. This is a good type of objectification.

Example of JSON.stringify() and JSON.parse()

const demoJsonObj = {
  mission: "CreateJsonStringify",
  timeToComplete: 10,
  useExistingFunction: false,
  reasons: ['Inquisitive','Masochist','Bragging Rights'],
  toolsAllowed:{
    language: "JavaScript",
    enhancer: "Coffee",
    motivation: "Binaural Beats",
    alternativeMethod: "Youtube - Check out my video tutorial"
  }
};

console.log(JSON.stringify(demoJsonObj));
// Output
//{"mission":"CreateJsonStringify","timeToComplete":10,"useExistingFunction":false,"reasons":["Inquisitive","Masochist","Bragging Rights"],"toolsAllowed":{"language":"JavaScript","enhancer":"Coffee","motivation":"Binaural Beats","alternativeMethod":"Youtube - Check out my video tutorial"}}


//Test the string is valid by parsing it back
console.log(JSON.parse(JSON.stringify(demoJsonObj)));

Ok that was nice and easy, we can pass the JavaScript Object and get a JSON String. Job done for 99% of folks out there. Not for us! Roll up your sleeves as we are only just about to GetCoding!

Where to begin?

Shall we jump in and start bashing out some code to start with? Or shall we have a think about what we are going to be doing here?

I’d start bashing on the keyboard, only to get 5 mins and and be like hmmmm. So here I am faced with the question how to we take a JSON Object and convert it into a JSON String?

What is a JSON Object? What can be in it? Do we need to cover all cases? Are there any weird things that could happen?

How do I go through each object item? What if it is an array of items? What if there is a object in the object? What if there is a array in the object or in the objects object array . . . . .does that even make sense?

Hmmm thats a lot of questions, Lets start with what is a JSON Object W3schools and MDN — I found the W3Schools page better it gave me a nice convenient list of what are valid JSON types

  • string
  • number
  • object
  • array
  • boolean
  • null

It also gave an example on how to loop through a JSON object. We are definitely going to need this!

//looping through the JSON Object using the object above
//variable is -- demoJsonObj -- just to remind you

for (const item in demoJsonObj) {
  console.log(item);
}

//This is handy, we can loop through the object and output each item. 

//Can you think how else we can use it?

This is excellent at least we have a starting point now, we know a bit about JSON and we definitely know that we need to handle these types. At some point we are going to need to check if the data we are looking at so lets make that code now.

Here your style preference can change how you write this, you could use if statements, switch or functions for each data type and return true/false.

function isStr(val){
    return typeof val === 'string';
}

function isNum(val){
 return typeof val === 'number';
}

// when checking a object we must ensure it is not null and not an array. Both null & Array has typeof object in JS
function isObj(val){
    return typeof val === 'object' && !Array.isArray(val) && val !== null;
};

// We need to check that it is an Array and also of type object

function isArray(val){
    return Array.isArray(val) && typeof val === 'object';
};

function isBool(val){
  return typeof val === 'boolean';
}

function isNull(val){
    return typeof val === 'string';
}

So that handles our Data types listed by W3Schools, there was a bit of knowledge I did have about type of for null and arrays returning as objects. If you didn’t have that you may get some weird results.

So now lets build out some code that will get a JSON Object and then loop through each item and check its type.

function CustomJsonStringify(obj){

 //check if it is string
  if(isStr(obj) ===true){
    return `"${obj}"`
  }
  if( isNum(obj) || isBool(obj)){
    return `${obj}`;
  }

  if(isArray(obj)){
    let arrayString = "";
    obj.forEach((val) => {
      arrayString += CustomJsonStringify;
      arrayString +=','
     });

    return `[${arrayString.replace(/,*$/, '')}]`;
  }




  // loop through each item in the object and handle it
  if(isObj(obj)){

        let objectString = ""; 
        let keys = Object.keys(obj);

    keys.forEach((key) => {
      let val = obj[key];
      objectString += `"${key}":${CustomJsonStringify(val)},`;

     });
     return `{${objectString.replace(/,*$/, '')}}`;

    }
  }


console.log(CustomJsonStringify(demoJsonObj));

//Pass string into JSON.parse() to check it is valid
console.log(JSON.parse(CustomJsonStringify(demoJsonObj)));

Conclusion

Here we have a basic stringify function , there are fringe cases which are not handled. and to make it more robust and a 1:1 equivalent we would need to add handling for

  • functions, undefined and Symbol values
  • Dates
  • NaN, Null and Infinity
  • Undefined

Hope this has been helpful to you, Ill have a youtube video going through this in the near future!

Code on GitHub

Related Posts