5

I'm all on board with functional programming in Javascript - particularly within the context of using React and Redux.

Something that I've been running into again and again, is how easy it is to accidentally mutate objects and create odd bugs.

That is, where the const keyword prevents the variable from being reassigned, it doesn't prevent the object itself from having its variables from being reassigned.

For example:

my-module.js

export const DEFAULT_HEADERS = {  //We are going to be using this const in other modules too. 
   foo: "foo"
}; 

export function someFunction(someCond) {
   const headers = DEFAULT_HEADERS; 
   if (someCond) {
       headers.foo = "bar"; //Don't do this!
   }
}; 

In this example - if we have imported DEFAULT_HEADERS to another module, we've mutated the value of foo, and screwed that up.

Now of course - the answer is to not reassign object properties like I have here.

But I don't have a way to prevent people from mutating objects like this.

Where this get more important, is when I have a should-be-immutable object that has a nested structure.

To do it correctly, we need to destructure the object at each level, as ...{} spread syntax only clones superficially.

For example:

const props = {
  alpha: {
    innerAlpha: {
      a: "aaa",
      b: "bbb",
    },

    innerAlphete: {
      b: "bbb",
      c: "ccc",
    }
  },

  beta: {
    foo: "foo",
    bar: "bar",
  }
}

//Now we want to change the value of props.innerAlpha.b to "BBB", but without mutating the original object. 

const props2 = { ...props,
  ...{
    alpha: {
      ...props.alpha,
      ...{
        innerAlpha: {
          ...props.alpha.innerAlpha,
          ...{
            b: "BBB"
          }
        }
      }
    }
  }
};


console.log(props);
console.log(props2);

And it's quite a pain to write code that way, so it's easy to see that someone would do something like:

   const props2 = {...props}; 
   props.alpha.innerAlpha.b = "BBB"; 

So my main question is - are there any proposals to make truly immutable objects in Javascript?

And also - is there a more convenient way to do immutable programming in Javascript?

4
  • immutable-js
    – Fabio
    Commented Feb 12, 2019 at 3:42
  • 3
    look up Object.freeze() and Object.seal(). These are native methods in ES6 and they might get you on the right track.
    – chharvey
    Commented Feb 12, 2019 at 6:08
  • @chharvey - Object to freeze only superficially freezes objects. You still need to freeze the whole structure.
    – dwjohnston
    Commented Feb 13, 2019 at 0:20
  • Correct. i wonder if you can use recursion to achieve what you want. The standards provide us with only the bare basics, but they need to remain unopinionated in order to stay lightweight and appease all environments. Then you can either build what you need based on what you know, or find a 3rd party library that will do it for you. If you have the time, I personally recommend the former route as it leads to a much deeper understanding.
    – chharvey
    Commented Feb 13, 2019 at 2:56

1 Answer 1

1

Aside from Object.freeze and Object.seal, those are excellent ideas. You could also wrap your state in an iif, expose only what you want private, and freeze or seal the rest. React does this. The DCI model also offers a twist on the actor model, where the state is handled at runtime by objects that are enabled or empowered via dynamic mixins. DCI Model And if you are trying to control state and encapsulation at the same time, there are design patterns for that too, GOF as the State Design Pattern and Strategy Pattern. We are not running into problems that the Old Guys have not run into before.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.