3

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?

dwjohnston
  • 11,163
  • 32
  • 99
  • 194
  • this is an interesting topic, however, I think it's off topic for stackoverflow since it's too broad a question – Pixelomo Feb 12 '19 at 03:16
  • [Object.freeze](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) (that you are describing if I'm not mistaken) is there since ES5. – Kaiido Feb 12 '19 at 03:19
  • @Kaiido - Object.freeze still doesn't freeze everything in the nesting. – dwjohnston Feb 12 '19 at 03:20
  • Yes you would have to [deep freeze](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#Examples) everything when generating your structure. To freeze **everything** would mean that the prototype chain would be completely broken, you couldn't inherit any method from global objects anymore, quite a pain in the optimizer. – Kaiido Feb 12 '19 at 03:24
  • Did you check immutablejs ? Here is a good [discussion](https://stackoverflow.com/questions/36726138/why-should-i-use-immutablejs-over-object-freeze) about that . – Whatatimetobealive Feb 12 '19 at 03:29
  • Indeed. immutable.js or mori. Or switch to reagent :) – Jared Smith Feb 12 '19 at 03:32

0 Answers0