【问题标题】:Why is there an isNaN() function in JavaScript but no isUndefined()?为什么 JavaScript 中有 isNaN() 函数而没有 isUndefined()?
【发布时间】:2014-12-13 02:42:08
【问题描述】:

为什么 JavaScript 中有 isNaN() 函数而 isUndefined() 必须写成:

typeof(...) != "undefined"

有什么我看不到的地方吗?

在我看来,写这个而不是isUndefined(testValue)真的很难看。

【问题讨论】:

  • 好问题。但我认为这个在 Programmers SE 中更好(概念性的东西)。此外,像 Underscore 这样的实用程序库有 _.isUndefined
  • 对 stackoverflow 非常失望。没有人费心完整地阅读这个问题。
  • @simonzack 这是一个愚蠢的问题。为什么应该isUndefined()?为什么不是isNull() 呢?还是isEmptyString()?还是is17()
  • 注意isNaN 不检查参数是否为NaN。相反,它检查强制为数字的参数是否为NaN。如果要检查参数是否为NaN,可以使用ES6 Number.isNaN

标签: javascript undefined nan


【解决方案1】:

这不是其他人已经回答的问题的直接答案,更多的是突出包含 isUndefined() 函数的库,供任何寻求快速解决方案并且他们能够使用它们的人使用。

Underscore 和 Lo-dash 都包含一个 isUndefined() 函数,后者是基于 Underscore 构建的。

【讨论】:

    【解决方案2】:

    用例var === undefined 几乎适用于所有地方,除了this answer 涵盖的情况,其中undefined 被分配了一个值,或者var 未定义。

    从后一种情况可以清楚地看出这种功能不存在的原因。如果var 未定义,那么调用假定的函数isUndefined(var) 将导致ReferenceError。但是引入一个新的关键字,例如isundefined var 可以解决这个问题。

    但尽管是有效的,上述两种情况都是对 javascript 的不良使用。这就是我认为不存在这样一个关键字的原因。

    【讨论】:

    • isUndefined() 不存在的原因是因为它没有必要。正如 Pointy 回复您对该问题的评论一样,如果我们有 isUndefined(),为什么我们不也有 isNull()is17()isNaN() 是必需的,因为 NaN 值彼此无法区分。 NaN 不等于 NaN。另一方面,undefined等于undefined
    • 问题的标题询问为什么isNaN() 存在但isUndefined() 不存在。您的回答根本没有提到NaN 以及为什么isNaN() 是ECMAScript 的一部分,而是假设isUndefined() 不是ECMAScript 的一部分。 isNaN() 是必需的函数,因为没有其他(简单)方法可以将值与 NaN 进行比较。另一方面,undefined 可以使用相等运算符===== 确定,因此根本不需要这样的函数。
    • @JamesDonnelly isNaN 很容易实现,所以你关于它为什么必须存在的论点是有缺陷的。 function isNaN(x){return x !== x;} - 它唯一不等于它自己的事实是如何识别它。
    • @AaronDufour 但是你必须在你创建的每个项目中定义这个函数,你需要检查一个值是否为NaN。正如我之前提到的,检查undefined 就像value === undefined 一样简单,而检查NaN 并不像value === NaN 那样简单。 isNaN() 函数比 isUndefined() 函数有用得多。同样,按照您的逻辑,当我们可以自己编写函数时,为什么还要在 ECMAScript 中预定义函数? :-) 请记住,这是由 ECMAScript 的创建者和 ECMAScript 6 的编辑决定的,而不是我。
    • @JamesDonnelly 我同意你在那里所说的一切,但你之前的评论中仍然没有为“isNaN() 是必要的”辩护。充其量只是一种便利——绝对不是必需品。
    【解决方案3】:

    根本不需要isUndefined() 函数。这背后的原因在ECMAScript specification中有解释:

    (请注意,NaN 值是由程序表达式 NaN 生成的。)在某些实现中,外部代码可能能够检测各种 Not-a-Number 值之间的差异,但这种行为取决于实现;对于 ECMAScript 代码,所有 NaN 值都无法相互区分

    isNaN() 函数用作检测某事物是否为 NaN 的一种方式,因为相等运算符在其上不起作用(如您所料,见下文)。一个NaN 值不等于另一个NaN 值:

    NaN === NaN; // false
    

    另一方面,undefined 是不同的,undefined 的值是可区分的:

    undefined === undefined; // true
    

    如果您对 isNaN() 函数的工作原理感到好奇,请参阅 ECMAScript 规范 also explains this for us

    1. 设 num 为 ToNumber(number)。
    2. ReturnIfAbrupt(num).
    3. 如果 num 为 NaN,则返回 true。
    4. 否则,返回 false。

    ECMAScript 代码测试值 X 是否为 NaN 的可靠方法是 X !== X 形式的表达式。当且仅当 X 为 NaN 时,结果才为真。

    NaN !== NaN; // true
    100 !== 100; // false
    
    var foo = NaN;
    foo !== foo; // true
    

    【讨论】:

    • NaN === NaN 是错误的实际上正是您不需要isNaN 的原因。正如您引用的文档所述,对NaN !== NaN 的测试完全足够了。因此,说isUndefined() 不存在是没有用的,因为它不需要,因为isNaN() 确实存在并且同样无用。
    • @LightnessRacesinOrbit 不是真的。要比较NaNisNaN() 函数会将值与自身进行比较。调用isNaN(myReallyLongObject.myReallyLongVariableName) 比调用myReallyLongObject.myReallyLongVariableName !== myReallyLongObject.myReallyLongVariableName 要好得多。使用undefined,您只需myReallyLongObject.myReallyLongVariableName === undefined。支票不是variable !== NaN,而是variable !== variable。这会使事情变得难以阅读,而 isNaN() 方法可以准确地告诉您正在检查的内容。
    • @James,您应该将最后一部分添加到您的答案中。至于为什么拥有isNaN() 函数是有意义的。人们可以将x !== x 到处乱写,但仅仅看一下检查的目的可能并不能立即清楚,因此在使用中存在更大的混淆和错误风险。 isNaN() 晶莹剔透。
    • 注意 isNaN 不会“检测某物是否为 NaN”。相反,它会检查强制编号的内容是否为NaN。检测某个东西是否为NaN,可以使用ES6 Number.isNaN代替。
    • 您误解了粗体子句。发生的情况是,IEEE 754(其中定义了双精度浮点格式)定义了许多不同的位模式,这些位模式都是 NaN——甚至对其中一些位模式赋予了不同的含义。粗体子句解释 ECMAScript 不提供任何方式来区分不同的位模式:所有 NaN 都是等价且可互换的。 NaN !== NaN 是一个完全独立的事实;在 NaN === NaN 的备用宇宙 ECMAScript 中,粗体子句仍然可能为真。
    【解决方案4】:

    isUndefined 可以写成

    testValue === undefined
    

    喜欢所有其他值。

    这不适用于NaN,但是作为NaN !== NaN。如果无法使用比较,则需要 isNaN 函数来检测 NaN 值。

    【讨论】:

      猜你喜欢
      • 2011-04-22
      • 1970-01-01
      • 2015-11-29
      • 2022-01-19
      • 2018-03-10
      • 2021-01-06
      • 2020-01-18
      • 1970-01-01
      相关资源
      最近更新 更多