Constant evolution in JS

Francisco Presencia
3 min readJan 6, 2020

--

In the beginning there was var. And it weakly defining that there was something there. It was lawless and everything could be done to it:

var user = { name: 'Sarah', friends: ['John'] };
user = null;
// No error

This dangerous beast had to be tamed, and the Javascript committee decided to add a variable declaration more stable, giving birth to let and const.

const came to create variables that cannot be modified:

const user = { name: 'Sarah', friends: ['John'] };
user = null;
// Error 🎉

But despite of its name indicating it’s a “constant”, its value can change easily:

const user = { name: 'Sarah', friends: ['John'] };
user.name = 'Peter';
// No error ¯\_(ツ)_/¯

People were abashed and React issued strict warnings on not mutating state and everyone was busy avoiding mutating state. There was a lot to learn about this new kid on the block and devs watched many tutorials.

Of course this was not sustainable, programmers having fun and avoiding mutations? Then something better, something that makes even the deeper values not able to change was created:

'use strict';
const
user = Object.freeze({ name: 'Sarah', friends: ['John'] });
user.name = 'Peter';
// Error if you activate "use strict" 🎉

“This time is for real” some people thought. And it seemed like all was good, until these fresh grads did horrible things to your -oh so- beautiful codebase and things broke in inexplicable ways.

It seemed that even if the object is defined as constant and frozen, it can still be modified if you go deep enough:

'use strict';
const
user = Object.freeze({ name: 'Sarah', friends: ['John'] });
user.friends[0] = 'Tim';
// No error ¯\_(ツ)_/¯

And everyone was very confused and put their arms up in the air, but it was too late. So the people said “this time we will elect our own leader”!

And immutable and immer were born, but they of course added some overhead in what could have been a beautiful native JS.

But I decided to finally learn a bit more about CS and walk the tree. This snippet as part of my React state management library Statux, but it’s so small that it can be shared here:

// Deep freeze any object
const freeze = obj => {
// Does not need freezing
if (typeof obj !== "object") return obj;
// Already frozen
if (Object.isFrozen(obj)) return obj;
// Freeze props recursively before freezing self
for (let key of Object.getOwnPropertyNames(obj)) {
if (Array.isArray(obj) && key === "length") continue;
obj[key] = typeof obj[key] === "object"
?
freeze(obj[key])
: obj[key];
}
return Object.freeze(obj);
};

And that’s it, now you can freeze any object you want with that snippet:

'use strict';// Using the freeze above
const
user = freeze({
name: '
Sarah',
friends
: ['John']
});
user.friends[0] = 'Tim';
// Error 🎉

This is a humorous introduction to JS constant evolution, I have nothing but deep respect for the amazing work of both the ECMAScript group and the JS community at large and love what we are building together.

--

--