【问题标题】:What is the reason for making Object.freeze() to fail silently?使 Object.freeze() 静默失败的原因是什么?
【发布时间】:2017-03-03 09:12:40
【问题描述】:

obj 发生突变时,为什么Object.freeze(obj)静默失败?

当不可变对象发生变异时,抛出比错误更合乎逻辑吗?然后,用户可以自行决定是否要将try catch 包裹在他的Object.freeze(obj) 周围。类似于我们需要用try catch 包装JSON.parse() 以避免出现空字符串或格式错误的JSON 的错误。

希望社区可以发表评论。

在几个答案和 cmets 后编辑:

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

【问题讨论】:

标签: javascript json object ecma


【解决方案1】:

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

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

假设我们有

'use strict'

const obj = Object.freeze({ test: true })

添加属性时出错:

obj.other = true
// TypeError: Can't add property another, object is not extensible

改变现有属性会抛出:

obj.test = false
// TypeError: Cannot assign to read only property 'test' of object '#<Object>'

删除属性会抛出:

delete obj.test
TypeError: Cannot delete property 'test' of #<Object>

如果想更详细地了解严格模式(强烈推荐),请查看official MDN docs for the differences

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

注意try/catch

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

if (Object.isFrozen(obj) {
  // Can't touch this!
}

【讨论】:

  • 在我的理解中,被冻结的对象将类似于全局不可变常量,开发人员知道它们是什么。只对每个对象使用Object.frozen() 是一种不好的做法,而且在每一行都使用Object.isFrozen() 是没有问题的。 Object.freeze() 类似于 ES6 中的 const。开发人员知道该对象是一个全局常量并且不应该更改,但如果他仍然试图绕过规则,他应该得到一个错误。
  • 并非对每个变量/对象使用constObject.frozen() 并检查它是否可变。该问题的目的是了解非严格模式下静默失败的必要性。
  • 我认为没有“必要性”——这个决定很可能是出于人体工程学。正如您自己所说,在任何地方都使用Object.isFrozen() 是不可行的,因此让操作静默失败更符合人体工程学。
  • Object.frozen() 在非严格模式下抛出错误,开发者不会用它来冻结每个对象。如果他愿意,那应该由他自行决定。解释器应该负责对错误代码发出警报。您不希望重新分配 const 变量并使其保持不变。
  • 注意在严格模式下是否调用Object.freeze()并不重要
【解决方案2】:

我认为这就是修改冻结对象静默失败的原因,

如果抛出错误,代码的执行将停止。尝试并抓住 语句可用于处理错误。用try可以吗 并捕获代码中每一行的语句以避免错误? 我觉得没有

1.在代码中不必要地使用 trycatch

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

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

假设不止一个对象被冻结。这将增加对更多trycatch 语句的需求。它可能会导致将代码的每一行都包含在 trycatch 块中

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多