Nodejs:global.isNaN vs Number.isNaN

Nodejs:global.isNaN vs Number.isNaN

TL;DR

  • global.isNaN(obj) 会先将 obj 转换成 number,再检查是否为 NaN
  • Number.isNaN(obj) 直接检查 obj 是否为 NaN
  • 如果你想要判断一个对象本身(不转换成 number)是否真的为 NaN,请使用 Number.isNaN(obj)

NaN

js 中有一个特殊的对象:NaN。它表示一个非法的数字(Not-a-Number), 它也是 js 中唯一一个 NaN === NaNfalse 的东西。

通常,我们使用 js 提供的 isNaN(obj) 方法来判断一个对象是不是 NaN。 然而 es6 规范中, Number 对象上同样有一个 isNaN(obj) 的方法(node.js 支持,部分浏览器也支持)。这两个有什么区别呢?

global.isNaN

global.isNaN(object) 会先将 object 转换成 number,然后再对其进行检查:

global.isNaN = function (obj) {
  obj = Number(obj);
  return !(obj === obj);
}

对不同的对象调用 global.isNaN,会得到下面结果:

isNaN(NaN);       // true
isNaN(undefined); // true
isNaN({});        // true

isNaN(true); // false isNaN(null); // false isNaN(37); // false

// strings isNaN(“37”); // false: “37” is converted to the number 37 which is not NaN isNaN(“37.37”); // false: “37.37” is converted to the number 37.37 which is not NaN isNaN(""); // false: the empty string is converted to 0 which is not NaN isNaN(" "); // false: a string with spaces is converted to 0 which is not NaN

// dates isNaN(new Date()); // false isNaN(new Date().toString()); // true

// This is a false positive and the reason why isNaN is not entirely reliable isNaN(“blabla”) // true: “blabla” is converted to a number. // Parsing this as a number fails and returns NaN

Number.isNaN

Number.isNaN(obj) 不会对 obj 做任何转换,直接进行检查:

Number.isNaN = function (obj) {
  return !(obj === obj);
}

对不同的对象调用 Number.isNaN,会得到下面结果:

Number.isNaN(NaN); // true
Number.isNaN(Number.NaN); // true
Number.isNaN(0 / 0) // true

// everything else: false Number.isNaN(undefined); Number.isNaN({});

Number.isNaN(true); Number.isNaN(null); Number.isNaN(37);

Number.isNaN(“37”); Number.isNaN(“37.37”); Number.isNaN(""); Number.isNaN(" "); Number.isNaN(“NaN”); Number.isNaN(“blabla”); // e.g. this would have been true with isNaN

在使用 isNaN 之前,请务必想清楚检查的目的,之后再选择用哪个方法进行判断。最后,附上一个进行类型判断的 node 模块: is-type-of

转载自:http://deadhorse.me/nodejs,js/2014/04/03/isNan-vs-Number.isNaN.html


4 回复

Node.js: global.isNaN vs Number.isNaN

TL;DR

  • global.isNaN(obj) 会先将 obj 转换成 number,再检查是否为 NaN
  • Number.isNaN(obj) 直接检查 obj 是否为 NaN
  • 如果你想要判断一个对象本身(不转换成 number)是否真的为 NaN,请使用 Number.isNaN(obj)

NaN

在 JavaScript 中,有一个特殊的值称为 NaN(Not-a-Number),表示一个非法的数字。值得注意的是,NaN 是唯一的 NaN !== NaN 的情况。

通常,我们使用 isNaN(obj) 方法来判断一个对象是否是 NaN。然而,ES6 规范中,Number 对象上也有一个 isNaN(obj) 的方法。那么这两个方法有什么区别呢?

global.isNaN

global.isNaN(object) 会先将 object 转换成 number,然后再对其进行检查:

function isNaN(obj) {
  obj = Number(obj);
  return !(obj === obj);
}

例如:

console.log(isNaN(NaN));       // true
console.log(isNaN(undefined)); // true
console.log(isNaN({}));        // true

console.log(isNaN(true));      // false
console.log(isNaN(null));      // false
console.log(isNaN(37));        // false

// 字符串
console.log(isNaN("37"));      // false: "37" 被转换为数字 37
console.log(isNaN("37.37"));   // false: "37.37" 被转换为数字 37.37
console.log(isNaN(""));        // false: 空字符串被转换为 0
console.log(isNaN(" "));       // false: 带空格的字符串被转换为 0

// 日期
console.log(isNaN(new Date()));                // false
console.log(isNaN(new Date().toString()));     // true

// 这是一个假阳性,因此 `isNaN` 并不是完全可靠的
console.log(isNaN("blabla"));  // true: "blabla" 被转换为 `NaN`

Number.isNaN

Number.isNaN(obj) 不会对 obj 做任何转换,直接进行检查:

function isNaN(obj) {
  return !(obj === obj);
}

例如:

console.log(Number.isNaN(NaN)); // true
console.log(Number.isNaN(Number.NaN)); // true
console.log(Number.isNaN(0 / 0)); // true

// 其他情况:false
console.log(Number.isNaN(undefined));
console.log(Number.isNaN({}));

console.log(Number.isNaN(true));
console.log(Number.isNaN(null));
console.log(Number.isNaN(37));

console.log(Number.isNaN("37"));
console.log(Number.isNaN("37.37"));
console.log(Number.isNaN(""));
console.log(Number.isNaN(" "));
console.log(Number.isNaN("NaN"));
console.log(Number.isNaN("blabla")); // 这个不会返回 true

总结

在使用 isNaN 之前,请确保理解其工作原理,并根据具体需求选择合适的方法。如果需要检查一个对象是否确实为 NaN,建议使用 Number.isNaN

更多关于类型判断的信息可以参考这个模块: is-type-of


转载自: http://deadhorse.me/nodejs,js/2014/04/03/isNan-vs-Number.isNaN.html


很好,收藏了~~

分析的这么细致

Node.js: global.isNaN vs Number.isNaN

在 Node.js 中,global.isNaNNumber.isNaN 都用于判断某个值是否为 NaN,但它们的工作方式有所不同。

global.isNaN

global.isNaN 会首先将传入的对象转换为数值,然后再判断该数值是否为 NaN。这意味着 global.isNaN 可能会返回意外的结果,因为它可能会将非数值转换为 NaN

console.log(global.isNaN(NaN));         // true
console.log(global.isNaN("37"));        // false
console.log(global.isNaN("blabla"));    // true

Number.isNaN

Number.isNaN 则不会将对象转换为数值,而是直接判断对象是否为 NaN。这使得 Number.isNaN 更加可靠,因为不会受到非数值对象的影响。

console.log(Number.isNaN(NaN));         // true
console.log(Number.isNaN("37"));        // false
console.log(Number.isNaN("blabla"));    // false

示例代码

为了更直观地理解两者的区别,可以看下面的示例代码:

function checkIsNaN(value) {
  console.log(`Value: ${value}, global.isNaN: ${global.isNaN(value)}, Number.isNaN: ${Number.isNaN(value)}`);
}

checkIsNaN(NaN);              // Value: NaN, global.isNaN: true, Number.isNaN: true
checkIsNaN("37");             // Value: 37, global.isNaN: false, Number.isNaN: false
checkIsNaN("blabla");         // Value: NaN, global.isNaN: true, Number.isNaN: false

总结

  • 如果你想确保判断的是真正的 NaN 对象而不是转换后的 NaN,请使用 Number.isNaN
  • global.isNaN 可能会将非数值对象转换为 NaN,从而导致误判。
回到顶部