为什么JavaScript中有isNaN()函数但没有isUndefined()?

Mem*_*eak 24 javascript nan undefined

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

typeof(...) != "undefined"
Run Code Online (Sandbox Code Playgroud)

我有没有看到一点?

在我看来,写这个而不仅仅是非常难看isUndefined(testValue).

Jam*_*lly 27

根本不需要isUndefined()功能.ECMAScript规范中解释了这背后的原因:

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

isNaN()函数用作检测某些东西是否NaN因为相等运算符不起作用(正如您所期望的那样,见下文)的方法.一个NaN值不等于另一个NaN值:

NaN === NaN; // false
Run Code Online (Sandbox Code Playgroud)

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

undefined === undefined; // true
Run Code Online (Sandbox Code Playgroud)

如果您对该isNaN()函数的工作原理感到好奇,ECMAScript规范也为我们解释了这一点:

  1. 设num是ToNumber(数字).
  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
Run Code Online (Sandbox Code Playgroud)

  • @LightnessRacesinOrbit不是真的.为了比较'NaN`,`isNaN()`函数将值与自身进行比较.调用`isNaN(myReallyLongObject.myReallyLongVariableName)`比调用`myReallyLongObject.myReallyLongVariableName!== myReallyLongObject.myReallyLongVariableName`要好得多.使用`undefined`,你只需要'myReallyLongObject.myReallyLongVariableName === undefined`.检查不是`变量!== NaN`,它是`变量!==变量`.这会让事情变得令人困惑,而`isNaN()`方法会告诉你究竟要检查什么. (11认同)
  • 你误解了粗体条款.会发生什么,IEEE 754(其中定义了双精度浮点格式)定义了许多不同的位模式,这些位模式都是NaN - 甚至对这些位模式中的某些位模式赋予了不同的含义.粗体条款解释说ECMAScript没有提供任何区分不同位模式的方法:所有NaN都是等价的和可互换的."NaN!== NaN"是一个完全独立的事实; 在一个替代宇宙ECMAScript中,粗体条款仍然可以是真的,其中"NaN === NaN". (3认同)
  • 那个'NaN === NaN`是假的,实际上也是你不需要`isNaN`的原因.正如您引用的文档所述,测试"NaN!== NaN"就足够了.因此,说'isUndefined()`不存在是没有用的,因为它不需要因为`isNaN()`确实存在而且确实是无用的. (2认同)

sim*_*ack 15

该用例var === undefined几乎无处不在,除了这个答案涵盖的情况,其中任何一个undefined被赋值,或者var未定义.

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

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

  • `isUndefined()`不存在的原因是因为它没有必要.正如Pointy回答你对这个问题的评论,如果我们有一个`isUndefined()`为什么我们也没有`isNull()`或`is17()`.`isNaN()`是必需的,因为NaN值彼此无法区分.`NaN`不等于'NaN`.另一方面,'undefined`,*等于`undefined`. (9认同)
  • @JamesDonnelly`isNaN`很容易实现,所以你为什么它必须存在的论点是有缺陷的.`function isNaN(x){return x!== x;}` - 它唯一不等于它的事实是如何识别它. (5认同)
  • @JamesDonnelly我同意你在那里所说的一切,但是对于"isNaN()来说仍然没有任何辩护"是你早期评论的必要条件.它充其量只是一种便利 - 绝对不是必需品. (5认同)
  • @AaronDufour但你必须在你创建的每个项目中定义这个函数,你需要检查一个值是否为"NaN".正如我之前提到的,检查`undefined`就像`value === undefined`一样简单,而检查NaN并不像`value === NaN`那么简单.`isNaN()`函数比`isUndefined()`函数更有用.同样,按照你的逻辑,当我们自己编写时,为什么要在ECMAScript中预先定义任何函数呢?:-)请记住,这是由ECMAScript的创建者和ECMAScript 6的编辑决定的,而不是我. (2认同)