Does ImmutableJS freeze objects?

(Goffreder) #1

Newbie question: does ImmutableJS freeze objects?

I thought I couldn’t do

let foo = Map(); = "baz";

console.log(; // baz

but I can. I expected an error, or at least that was undefined. What am I missing?

(Troy Rhinehart) #2

Immutable.Map has a get and set function for getting/setting values.

import { Map } from 'immutable';

const foo = Map();
foo.set('bar', 'baz');
console.log(foo.get('bar')); // undefined, every 'set' creates a new Map hence foo is immutable

const foo2 = foo.set('bar', 'baz');
console.log(foo2.get('bar')); // baz

(Andy Edwards) #3

The point of ImmutableJS isn’t to freeze objects or prevent you from tacking on new properties. Its purpose is to provide efficient copy-on-write mutations:

const bigObject = {...(hundreds of key-value pairs)}

const foo = Map(bigObject)
// the following should be more time/memory efficient 
// (beyond a certain size) than copying with {...bigObject, bar: 'baz'}
const newfoo = foo.set('bar', 'baz')
// also, foo has not been modified; only newfoo contains the change.

Does that make sense?

One other crucial feature is that if foo.get('bar') === 'baz', foo.set('bar', 'baz') will just return foo. Doing the same thing with plain JS objects is awkward:

const copy = === 'baz'
  ? bigObject
  : {...bigObject, bar: 'baz'}

(Goffreder) #4

Thank you all. So the point is “always make sure you use get and set to interoperate with the state”, correct? But how is this preventing me from making mistakes? If i forget to use set to add a property I can easily access (and mutate) that property.

Another question: why doesn’t it leverage the possibility to freeze objects?

(Troy Rhinehart) #5

@goffreder if you forget to use set, you wouldn’t be able to get the value using get. You would mutate the Immutable instance, but not the data held within it.