如果你能在字符串上找到 属性 个名字,为什么你不能在 undefined 上找到它们?

If you can find property names on strings, why can't you find them on undefined?

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

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

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

在许多语言中,这些类型的不变违规和非法操作会导致显式错误,无论是在运行时还是在编译中。您越早发现问题(由于编译器错误、警告或测试期间的运行时 crash/error),您就可以更快更轻松地修复错误。

JS 以弱类型和其他宽松的设计选择而顽固地引发错误而著称。您可以对几乎任何类型进行连接和执行数学运算,或者使用强制相等运算符 == 比较值并以 anyone's-guess results 结束。原因主要是历史原因:JS 是为快速、简单的脚本而设计的,而不是为今天的大型单页应用程序而设计的。

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

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

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

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

正如我在评论中提到的,React 还 made changes 归因于“快速失败、大声失败、努力失败”的哲学:

[...] in our experience it is worse to leave corrupted UI in place than to completely remove it. For example, in a product like Messenger leaving the broken UI visible could lead to somebody sending a message to the wrong person. Similarly, it is worse for a payments app to display a wrong amount than to render nothing.

[...] This change means that as you migrate to React 16, you will likely uncover existing crashes in your application that have been unnoticed before.

[...] We also encourage you to use JS error reporting services (or build your own) so that you can learn about unhandled exceptions as they happen in production, and fix them.

以下是 article on javascript.info 的建议:

Don't overuse the optional chaining

We should use ?. only where it's ok that something doesn't exist.

For example, if according to our coding logic user object must exist, but address is optional, then we should write user.address?.street, but not user?.address?.street.

So, if user happens to be undefined due to a mistake, we’ll see a programming error about it and fix it. Otherwise, coding errors can be silenced where not appropriate, and become more difficult to debug.

这里有一个很好的 blog post 关于这个问题