const t = Object.freeze({foo: "bar"});
// throws an error in strict mode,
// silently does nothing otherwise
t.foo = "baz";
// prints "bar"
console.log(t.foo);
The tricky part is that it does not do so recursively: const t2 = Object.freeze({foo: {bar: "baz"}});
// bar is still mutable
t2.foo.bar = "oh no!";
// prints "oh no!"
console.log(t2.foo.bar);
Still, one can easily write a function to recursively do a depth-first walk on an object and make everything immutable, so this is not really a concern in practice (if anything it gives you more flexibility).Anyway, what I think Miller meant is that immutability is not the main reason why they introduced Object.freeze.
If I understand correctly, the main idea is to prevent people from inserting malicious code in the prototype chain (or anywhere else they might be able to).
Because JavaScript is prototype based I could in theory create a new Array class that uses the original Array class as its own prototype, then replace the Array class with itself. If you then create a new array it would still work like a regular one - it just goes up the prototype chain after all.
The malicious part is that this custom array class could then also override all Array methods to secretly watch your data and send stuff to the web without you noticing, or do anything else really. Because, again, it can just call the original method of its prototype to also behave as normal without anyone noticing.
Object.freeze would let you make sure none of the fundamental JavaScript objects can be tampered with.
The other thing is that you can ensure that any the library you create cannot be tampered with by third-party libraries.