DEV Community

Francisco Presencia
Francisco Presencia

Posted on • Originally published at Medium

Constant evolution in JS

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 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 and the abstraction cloud was too high. So the people said “this time we will elect our own leader”!

Inception meme

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:

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

Top comments (1)

Collapse
 
diek profile image
diek

And which is the reason I would like to "freeze" an object?