使 Object.freeze() 静默失败的原因是什么?

Ven*_*SGS 3 javascript json object ecma

为什么当它发生变异时Object.freeze(obj)默默地失败obj

当不可变对象发生变异时,抛出比错误更合乎逻辑吗?然后,如果用户想将 a 包裹try catch在他的Object.freeze(obj). 类似于我们如何需要包装JSON.parse()try catch,以避免错误与空字符串或JSON格式不正确的。

我希望社区可以发表评论。

在几个答案和评论后编辑:

据了解,Object.frozen()严格模式下会抛出错误。但是为什么非严格模式下方法需要静默失败呢?

Rob*_*ann 5

Object.freeze() 在严格模式下确实抛出。

在严格模式下,以下程序将在任何时候在冻结对象上添加、改变或删除属性时抛出。

假设我们有

'use strict'

const obj = Object.freeze({ test: true })
Run Code Online (Sandbox Code Playgroud)

添加属性时出错:

obj.other = true
// TypeError: Can't add property another, object is not extensible
Run Code Online (Sandbox Code Playgroud)

改变现有的属性会抛出:

obj.test = false
// TypeError: Cannot assign to read only property 'test' of object '#<Object>'
Run Code Online (Sandbox Code Playgroud)

删除属性抛出:

delete obj.test
TypeError: Cannot delete property 'test' of #<Object>
Run Code Online (Sandbox Code Playgroud)

如果想更详细地了解严格模式(强烈推荐),请查看官方 MDN 文档以了解差异

关于这个话题的意见各不相同——人们会期望抛出对象的突变,因为“你正在做一些你不应该做的事情”,而其他人可能会说,如果你Object.freeze()做了某事,你只是想防止对其进行任何修改。并且你成功地完成了。如果它导致应用程序因突变而崩溃,程序员将别无选择,只能检查他们没有创建的所有对象是否冻结,或者他们必须将所有此类操作包装在try/catch块中。这要求太多了。

注意事项 try/catch

您可以try/catch通过检查对象的温度来避免在块中包装属性操作:

if (Object.isFrozen(obj) {
  // Can't touch this!
}
Run Code Online (Sandbox Code Playgroud)


Kir*_*ira -2

我认为这就是为什么修改冻结对象会默默失败,

如果抛出错误,代码的执行将停止。Try 和 catch 语句可用于处理错误。是否可以在代码中的每一行使用 try 和 catch 语句来避免错误?我想不是

1.代码中不必要的使用tryand块catch

假设一个对象在控制流中的某个时刻被冻结。代码中可能有很多行尝试添加新属性或修改冻结对象中现有属性的值。在这种情况下,如果抛出错误,那么您需要在所有这些代码行中添加try和块。catch

2. 可以冻结任意数量的对象

假设有多个对象被冻结。try这将增加对更多声明的需求catch。它可能会导致将代码的每一行都用tryandcatch块括起来