首页 > 解决方案 > 如果可以在字符串上找到属性名称,为什么在 undefined 上找不到呢?

问题描述

你可以将 undefined 的全局变量更改为一个值,你可以从字符串中读取一个属性,但是你不能读取 undefined 的属性。

前两个(你可以做的)似乎完全没用,第三个是我认为大多数开发人员都喜欢工作的东西。如果您进行 API 调用并尝试处理复杂数据,为什么不直接评估 undefined.undefined.undefined.undefined = undefined 而不是让程序崩溃呢?我知道可选链接,但我很好奇为什么这甚至是一个问题。这似乎是一个简单的修复,但我猜有一些 idk 关于。

标签: javascriptobjectundefined

解决方案


编程中的错误点在于它们会通知您严重的合同违规或非法状态。你期望某些东西被定义,但事实并非如此。您期望某物是某种类型,但事实并非如此。通常,程序不应该尝试在违反合同的情况下继续执行,如果应该,您应该明确指出并至少记录违规行为,而不是埋头于沙子中完全压制它。

在许多语言中,这类不变的违规和非法操作会在运行时或编译时导致显式错误。您越早发现问题(由于测试期间的编译器错误、警告或运行时崩溃/错误),您可以越早、越容易地修复错误。

由于弱类型和其他宽松的设计选择,JS 以顽固地引发错误而闻名。您可以对几乎任何类型进行连接并执行数学运算,或者使用强制相等运算符比较值并得到任何==的猜测 结果。原因主要是历史原因:JS 是为快速、简单的脚本而设计的,而不是为当今的大量单页应用程序而设计的。

像 TypeScript 这样的技术存在的原因本质上是向 JavaScript添加错误,以使程序更安全,并支持 1995 年设计 JS 时从未设想过的那种大型工业级应用程序。在 TS 的情况下,这些错误纯粹是编译时的,但是像 Python 这样的其他语言不会让你做很多 JS 在运行时所做的事情,比如添加两个不同的类型值"abc" + 42,这会引发一个TypeError(dictionary [a sort of Map] 访问也会引发错误;您必须选择使用等效于undefined) 的默认值。

同样,JS 的严格模式“通过将它们更改为抛出错误来消除一些 JavaScript 静默错误”。

相反的理念是抑制错误,这正是可选链接运算符?.提供的,听起来你建议默认对象属性运算符.也应该这样做。这是undefined在对象不存在时返回的代码的语法糖,偶尔使用它来保持代码简洁和传达意图是很好的,基本上说“看,我意识到这个特定的访问可能在一个未定义的对象上,而我的代码被设计成它期望这种情况,并将继续表达式评估为undefined“。

但这不是默认行为是一件好事:它本质上是在抑制错误,这与"abc" * 42返回默认值NaN而不是在 JS 中引发类型错误的基本原理几乎相同。为什么你会想要这个?可能永远不会,因此 JS 的声誉是不安全的。

正如我在评论中提到的,React 也做出了改变,将其归结为“快速失败、大声失败、努力失败”的理念:

[...] 根据我们的经验,保留损坏的 UI 比完全删除它更糟糕。例如,在像 Messenger 这样的产品中,让损坏的 UI 可见可能会导致某人向错误的人发送消息。同样,支付应用显示错误的金额比什么都不渲染更糟糕。

[...] 这一变化意味着,当您迁移到 React 16 时,您可能会发现应用程序中存在的以前未被注意到的崩溃。

[...] 我们还鼓励您使用 JS 错误报告服务(或构建您自己的),以便您可以了解生产中发生的未处理异常并修复它们。

以下是javascript.info 上一篇文章的建议:

不要过度使用可选链

我们应该?.只在某些东西不存在的情况下使用。

例如,如果根据我们的编码逻辑user对象必须存在,但是address是可选的,那么我们应该写user.address?.street,而不是user?.address?.street

因此,如果user碰巧由于错误而未定义,我们将看到有关它的编程错误并修复它。否则,编码错误可能会在不合适的地方被忽略,并且变得更难以调试。

这是一篇关于此事的不错的博客文章


推荐阅读