Object.freeze()
does throw, in strict mode.
In strict mode, the following program will throw any time a property is added, mutated or deleted on the frozen object.
Assume we have
'use strict'
const obj = Object.freeze({ test: true })
Error when adding a property:
obj.other = true
// TypeError: Can't add property another, object is not extensible
Mutating an existing property throws:
obj.test = false
// TypeError: Cannot assign to read only property 'test' of object '#<Object>'
Deleting a property throws:
delete obj.test
TypeError: Cannot delete property 'test' of #<Object>
If would like to understand strict mode in more detail (highly recommended) have a look at the official MDN docs for the differences.
The opinions on this topic vary - one would expect mutations of the object to throw because "you are doing something you should not be doing" while others might say that if you Object.freeze()
something, you just want to prevent any modifications to it. And that you successfully accomplish. If it caused applications to crash on mutations, programmers would have no choice but to either check all objects they did not create for their frozenness or they would have to wrap all such operations in try/catch
block. This is simply too much to ask.
Note about try/catch
You can avoid wrapping property manipulations in try/catch
blocks simply by checking the object's temperature :
if (Object.isFrozen(obj)) {
// Can't touch this!
}