Don’t go crazy

Sankar Ganesh
know-javascript
Published in
3 min readJun 6, 2020

The Javascript Engine let you do numerous things. That which is powerful should be dealt with care. If you go crazy and miss the track you get hit. Always be mindful about running on the end-user browsers. You can introduce error on-the-fly, but you can’t reverse them. I have broken the web several times so the pulse got settled now. If you are one among the craziest drivers out there, you’re just one step away from getting hit. So, I would recommend you to revisit the way you deal with Javascript.

Let’s talk about one of the costliest operations in Javascript

JSON.stringify

It has to iterate the object properties, and it’s prototypal chain to gather the key, value pairs and create the output string to return. If this is the case, unless this is the desired output of using JSON.stringify, it’s always better to avoid the usage and revisit the solution that you’re trying to solve

I call Javascript as a loosely typed language. The books read them as dynamically typed language. Both are same, but with respect to this operation it brings you more pain and it’s susceptible of getting error. When we say dynamically typed language, we can’t decide the datatype of the object when it’s created. This the power of Javascript too! But the runtime value, and it’s changing datatype bound to return unexpected results in your program. The other dependent module will start misbehaving from this results. Let’s see how this works, and correct the error with a fix.

let node = {
firstName: 'John',
lastName: 'Doe',
address: {
street: 'Buffalo Street',
city: 'NewYork'
}
};

This is a perfect object with three properties firstName lastName and address Now let’s play around with JSON.stringify

// Run stringify against the variable 'node'
JSON.stringify(node);
// Output contains all properties, values and properties of properties and it's corresponding value"{"firstName":"John","lastName":"Doe","address":{"street":"Buffalo Street","city":"NewYork"}}"Note: This confirms that this operation is costly. Every time when you run this, it iterates again and produce results. The return value is not cached.

Things are good and perfect until this point. Now let’s try the mix and match.

Say for example you introduce another property to this called fullName and it goes as follows

// Add a property called fullName to concatenate the names
node.fullName = function() {
return `${this.firstName} ${this.lastName}`;
};
// Rerun the stringify function to check, it returns same output
JSON.stringify(node);
// Output
{"firstName":"John","lastName":"Doe","address":{"street":"Buffalo Street","city":"NewYork"}}"
Note: This is because JSON doesn't allow methods / functions any runtime datatypes will not produce expected results

If you think it is not acceptable, I would say this is ok. Because there is no error also we may not want to include the fullName return value in the stringify results. Let’s make it even more crazy

// Now introduce a pointer and make it point to itself
node.next = node;
// Rerun the stringify function you will see this error
JSON.stringify(node);
// Output is an error
VM1208:1 Uncaught TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Object'
--- property 'next' closes the circle
at JSON.stringify (<anonymous>)
at <anonymous>:1:6
Note: Why so? Because it iterates the properties and properties of properties this creates a circular structure now since 'node.next' is pointing to itself

How you deal with this now? Javascript let you fix this with an alternate

// Method toJSON can be added to any Javascript object so this will be invoked by Javascript Engine when you run JSON.stringify against the objectnode.toJSON = function() {
return {
firstName: this.firstName,
lastName: this.lastName,
fullName: this.fullName(),
address: {
street: this.address.street,
city: this.address.city
}
};
}
// Rerun the stringify function you will see the expected output with no error
JSON.stringify(node);
// Output
"{"firstName":"John","lastName":"Doe","fullName":"John Doe","address":{"street":"Buffalo Street","city":"NewYork"}}"

Now you can add any dynamic type like links, methods and other functions as needed. The function part which JSON can’t process Javascript let us fix this using the toJSON method. It’s not a fashion to love everything. Javascript let you express your love with desires.

--

--

Sankar Ganesh
know-javascript

Javascript Evangelist, Young Husband, Father of 2, Broken the web several times