DEV Community

Cover image for The secret power of JSON stringify

The secret power of JSON stringify

Gábor Soós on October 22, 2019

There are many functions in Javascript that do their job. We use them daily, but we don't know about their extra features. At one day, we look at i...
Collapse
 
sidvishnoi profile image
Sid Vishnoi • Edited

Regarding the second items white list (array) argument:
We can use it to create a simple object hashing function (similar to object-hash, but with limitation of maximum object depth 1). The important thing is, JSON.stringify(obj) may not follow property order, which matters when the serialization is input for hashing/checksum. Instead we can pass Object.keys(obj).sort() as the 2nd argument, and the JSON will be stringified in that property order only.

function objectHash(obj: object): string {
  const str = JSON.stringify(obj, Object.keys(obj).sort());
  return createHash('sha1').update(str).digest('hex');
}
Enter fullscreen mode Exit fullscreen mode

View code snippet for client-side at GitHub
View code snippet for Node.js at GitHub and tests

Collapse
 
neilcodes profile image
Neil

This is kind of horrifying and I love it.

Collapse
 
martinratinaud profile image
Martin Ratinaud

Brilliant! thanks

Collapse
 
getclibu profile image
Neville Franks • Edited

I'd been looking everywhere to find a simple way to get JSON.stringify() to output items in a specific order. You post provided exactly what I needed to do what I wanted.

Unfortunately upon reading the JSON.stringify() docs I can't find any information on using a replacer array to set keys order. Only info about whitelists. Can you point to any docs on this?

Some other info I found that may be if interest to others: "sort object properties and JSON.stringify" - tfzx.net/article/499097.html

Thanks so much for your post.

Collapse
 
sidvishnoi profile image
Sid Vishnoi • Edited

From tc39.es/ecma262/#sec-json.stringify :

  1. 4.b.ii: If Type(replacer) is [Array]:
  2. 4.b.ii.g: If item is not undefined and item is not currently an element of PropertyList, then Append item to the end of PropertyList.

and later tc39.es/ecma262/#sec-serializejson... :

  1. 5.a: Let K be state.[[PropertyList]].
  2. 8: For each element P of K, do:
  3. 8.v: Append member to partial.
Thread Thread
 
getclibu profile image
Neville Franks

Thanks for that. Pity it is missing from the MDN Doc's. For some reason the links didn't take me to the relevant sections.

Thread Thread
 
sidvishnoi profile image
Sid Vishnoi

Updated links. DEV included trailing : in links, so they broke.

Thread Thread
 
getclibu profile image
Neville Franks

Thanks, the links now work.

I didn't pick up on the ", but with limitation of maximum object depth 1" issue and I need to handle objects with depth > 1.

After some more searching I found this article which is a collection of code snippets. tfzx.net/article/499097.html

The code that worked for me is:

    var allKeys = [];
    JSON.stringify( json, function( key, value ){ allKeys.push( key ); return value; } )
    allKeys.sort();
Enter fullscreen mode Exit fullscreen mode

which is from: stackoverflow.com/a/53593328/91300

Collapse
 
sonicoder profile image
Gábor Soós

Wow, didn't know it. Nice snippet! I always learn something new.

Collapse
 
thirdy profile image
APerfectCircle

Nice to know. However, being a java developer, this brings me to think that this should be a built-in functionality. Doesn't plain JS have hashing function for all it's objects?

Collapse
 
sidvishnoi profile image
Sid Vishnoi

No. JS doesn't expose any hashing function for any of its supported types.

Collapse
 
areljannc profile image
AJ Clemente

Wow! I'm a big fan of writing applications with JavaScript and its wide-varieties of libraries. I also don't post at all, ever, on any social platforms.

But this post is the first time that made we want to login and comment something.

Thanks for this amazing post! It's amazing that these simple methods are overlooked by many developers. Learning about this just now is the reason why I love programming.

Collapse
 
sonicoder profile image
Gábor Soós

Comments like this keep me motivated to keep on writing 👍 Thanks

Collapse
 
rose profile image
Rose

Great post, I use JSON.stringify all the time and I never new about this 😳love finding out about these nooks and crannies of JS.

Collapse
 
sonicoder profile image
Gábor Soós

Glad it showed something new 👍

Collapse
 
kenbellows profile image
Ken Bellows

I've been using JavaScript deeply for a long time and it's very rare that I learn something new about old parts of JavaScript, but you've taught me two new things! I knew about the replacer function, I knew about the indentation, I even knew about toJSON, but I had never heard of either the property whitelist array or the indentation string options before! Thanks for the knowledge! 👏👏👏

Collapse
 
sonicoder profile image
Gábor Soós

I have used the indentation for a long time, but that null value before it always bothered me 😀

Collapse
 
sambenskin profile image
Sam Benskin

Excellent article, I've never looked into the other arguments and the toJSON functionality is especially brilliant. Thanks for sharing!

Collapse
 
sonicoder profile image
Gábor Soós

toJSON was also absolutely new for me also

Collapse
 
nditanaka profile image
Tanaka

Thanks for the great post! Is there a way to easily unstringify text with a JavaScript? A kind of opposite of the stringify function? eg. how to remove the quotation marks in a dictionary of key-value pairs like {"name":"Tim", "age": "22"}. In this case, removing them just from the age value?

I have a more detailed version of this question on Stack Overflow that's been a little daunting to work around:

stackoverflow.com/questions/653516...

Thanks for the great article again!

Collapse
 
jdhinvicara profile image
John Harding

I am especially excited to be able to prefix my stringified objects with a unicorn!! 🦄🦄🦄

Seriously though, great article - every time I typed that null I wondered what that second argument was for and never got around to looking...

Thanks.

Collapse
 
sonicoder profile image
Gábor Soós

Thanks, unicorn all the way!!! 🦄🦄🦄

Collapse
 
suprsidr profile image
Wayne Patterson

Another super power is deep copying objects dassur.ma/things/deep-copy/

Collapse
 
mdsardar profile image
Mohammed Sardar

Thanks for the detailed sharing. Nice reading. It turned me very hunger for Java Script knowledge.

Collapse
 
sonicoder profile image
Gábor Soós

Stay hungry 👍

Collapse
 
fceruti profile image
fceruti

Thank you so much! Thanks to people like you we learn something new every day :)

Collapse
 
torben74 profile image
Torben74

I've been using stringify for years and had no idea how powerful it is. Great article. Thanks.

Collapse
 
matthieudesprez profile image
Matthieu Desprez

Thank you, I learned some useful tips reading your article :)

Collapse
 
panayiotisgeorgiou profile image
Panayiotis Georgiou

Thank you so much!

Collapse
 
briandesousa1 profile image
Brian De Sousa

Well done! Didn't know about those other arguments. The toJSON method is an interesting capability too. Thanks!

Collapse
 
sonicoder profile image
Gábor Soós

Thanks, yes indeed a real game changer

Collapse
 
nalani profile image
nalani5210 • Edited

The writing is very good, and I hope this online JSON tool website can help you in peacetime.
jsonformatting.com/

Collapse
 
cbmgit profile image
codeblogmoney

Awesome article, I think so these kinds of tools are using the same functions. codebeautify.org/jsonviewer and jsonformatter.org/json-parser

Collapse
 
yorchi profile image
Jorge Andrade

awesome, new thing learned!

Collapse
 
antonrusak profile image
Anton Rusak

Ha! The method looks so simple that I never even thought of reading MDN on it :) Thank you man for pointing us out to these awesome features. toJSON is the most promising part, I believe.