【问题标题】:a.b < 0, why does this not throw an error when a.b === undefined?a.b < 0,为什么在 a.b === undefined 时不会抛出错误?
【发布时间】:2019-10-30 01:31:27
【问题描述】:

一个错字结束了

a.b > 0

a.b 未定义。根据 MDN (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Greater_than_operator),比较在操作数上调用 .valueOf()。所以应该是

a.b.valueOf() > 0

但这实际上会引发一个似乎不会发生的错误。相反,这似乎被评估了:

undefined > 0

我是不是误会了什么?

在我的例子中,这导致了 Node.js 代码中的静默错误。我当然希望抛出一个错误。

我可以在不明确检查操作数的情况下处理这个问题吗?


编辑:freeCodeCamp 似乎比 MDN 更正确地描述了这一点:

https://guide.freecodecamp.org/javascript/comparison-operators/

但我仍然想知道如何最简单的方法来处理这个问题而不会被简单的拼写错误所困。

【问题讨论】:

  • 如果 a 未定义并且您尝试访问 a.b,它可能会引发错误,在您尝试访问 a.b 时是否已定义?
  • @AlexanderStaroselsky 是的,正如我所说,a.bundefined(这意味着 a !== undefined
  • @AlexanderStaroselsky 嗯,我没有在问题中清楚地写出来。感谢您指出。
  • "比较在操作数上调用.valueOf()" - 仅当操作数是一个对象时。它不会在原始值上这样做
  • @Leo 哦,哇。我现在已经修复了 MDN。

标签: javascript node.js comparison throw operands


【解决方案1】:

查看specification:它的作用is

  1. 令 r 为执行抽象关系比较的结果 lval

which does,它首先尝试将每一方强制转换为原语:

一个。让 px 成为 ? ToPrimitive(x, 提示号)。

b.让 py 成为? ToPrimitive(y, 提示号)。

undefined 已经是一个原始的 - 没有抛出任何东西。然后,它确实:

让 nx 是 ? ToNumeric(px)。

让你成为? ToNumeric(py)。

undefined 转换为数字也不会抛出,但会返回NaN

console.log(Number(undefined));

那么我们就去

如果 Type(nx) 与 Type(ny) 相同,则返回 Type(nx)::lessThan(nx, ny)。

其中nxNaNny 是0。lessThannxNaN 时返回undefined,描述here

  1. 如果 x 为 NaN,则返回 undefined。

然后,回到答案开头的5. 之后的步骤:

  1. 如果 r 未定义,则返回 false。否则,返回 r。

结果是undefined,所以返回false(没有抛出错误)。


应该是这样的

  a.b.valueOf() > 0

只有一个对象&lt;评估过程中会调用valueOf(在上面的a. Let px be ? ToPrimitive(x, hint Number).中)。 undefined 不是一个对象 - 它已经是一个原语,因此在该步骤不会发生额外的转换。

我当然希望抛出一个错误。

我可以在不明确检查操作数的情况下处理这个问题吗?

不是真的,但这应该不难做到——如果你不确定,请先检查a.b 是否是一个数字。 if (typeof a.b === 'number')。没有错。

【讨论】:

  • 谢谢,这是一个很好的解释。这意味着 MDN 简化了太多(在我给出的链接中)。然而,我也在寻找一种安全的方法来处理这个问题。
  • 谢谢,所以我必须明确检查操作数。
猜你喜欢
  • 1970-01-01
  • 2021-11-20
  • 1970-01-01
  • 2015-03-27
  • 1970-01-01
  • 1970-01-01
  • 2013-03-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多