3 ms·
var array = Immutable(["totally", "immutable", {hammer: "Can’t Touch This"}]); array[1] = "I'm going to mutate you!" array[1] // "immutable" I find it a l
by arasmussen 12y ago
var array = Immutable(["totally", "immutable", {hammer: "Can’t Touch This"}]);
array[1] = "I'm going to mutate you!"
array[1] // "immutable"
I find it a little weird that the result of trying to mutate an immutable object is to silently fail the mutation. Couldn't this hide errors where the developer expects something to mutate because they didn't realize it was immutable? Shouldn't it throw instead?
Edit: After reading the documentation more thoroughly, I saw "All the methods that would normally mutate the data structures instead throw ImmutableError." Looks like the first section isn't actually accurate then?
- rtfeldman 12y ago(Library author here.) Unfortunately, in JavaScript it's not possible to override array element reassignment behavior. You can call Object.freeze on the array, which makes reassignment silently do nothing, but you cannot override it to throw an exception. The reason the docs say "the methods that would normally mutate..." is that in the specific case of methods (e.g. array.push()), the library can and does override them to throw exceptions. I would certainly prefer to make that example throw an exception, but it's simply not possible in JS. :)
- underwater 12y agoObject.freeze will throw if you `'use strict';`.
- rtfeldman 12y agoVery true...I should note that in the documentation. Thanks!
- arasmussen 12y agoThanks for sharing that tidbit of information. I did not know that and now I do, I appreciate it! I wonder what the reason behind that is, if you're feeling extra motivated you could even look into having a conversation with the folks who decide what future versions of JS look like to add something like it. I am a huge proponent of immutability and can see how being able to override array element assignment behaviors would improve your library.
- geocar 12y agoObject.defineProperty(x,'foo',{set:function() { throw new Error(69) }})
- vjeux 12y agoYou can define a setter that throws in order to throw without using 'use strict;'. However, additions will still be silent :( https://gist.github.com/vjeux/6b390e6a6bb51e24b646 https://gist.github.com/vjeux/6b390e6a6bb51e24b646 __DEV__ = true; var array = ['a', 'b', 'c'] deepFreezeAndThrowOnMutationInDev(array) array[0] = 10; Error: You attempted to set the key `0` with the value `10` on an object that is meant to be immutable and has been frozen.
- virmundi 12y agoI spent the better part of an hour cursing about this. Chrome returns frozen objects from Web SQL. Now I didn't know that a poor language like Javascript had a Frozen! No errors! Finally found it when I queried for Angular failing to update objects because the looked immutable.