Search code examples
javascriptimmutabilityimmutable.js

Why is it possible to mutate the value of an item in an Immutable.List?


Immutable.List does not seem to prevent you treating it as a mutable array:

const Immutable =require( 'immutable');
const l = Immutable.List([1,2,3,4,5]);
l[4] = 9;

console.log(l[4], l.get(4)) // outputs 9, 5

Runkit

This seems surprising, and doesn't appear to be addressed in the documentation.

What am I misunderstanding here? I had imagined that Immutable.JS was somehow protecting you from mutating things, but I take it that it requires you to stick to the defined API to get those benefits?


Solution

  • It seems like Immutable handles immutability internally. If you log the list itself at the end of your code, it reads

    List {
      '4': 9,
      size: 5,
      _origin: 0,
      _capacity: 5,
      _level: 5,
      _root: null,
      _tail: VNode { array: [ 1, 2, 3, 4, 5 ], ownerID: undefined },
      __ownerID: undefined,
      __hash: undefined,
      __altered: false
    }
    

    So when you go l[4] = 9, you're actually adding a new property to the list object, rather than the internal representation of the list.

    If you use

    Object.freeze(l)
    

    before the call, then it works properly