我需要在Javascript中比较两个数值是否相等。这些值可能是NaN
。
我想到了以下代码:
if (val1 == val2 || isNaN(val1) && isNaN(val2)) ...
代码目前可以正常运行,但我觉得它太臃肿了。我想让它更简洁。有什么建议吗?
我需要在Javascript中比较两个数值是否相等。这些值可能是NaN
。
我想到了以下代码:
if (val1 == val2 || isNaN(val1) && isNaN(val2)) ...
代码目前可以正常运行,但我觉得它太臃肿了。我想让它更简洁。有什么建议吗?
if(val1 == val2 || (isNaN(val1) && isNaN(val2)))
没有需要改进的地方。只需添加括号以使它对每个人更加清晰明了。
NaN === NaN
应该返回 true。 - Esailija避免使用isNaN
,它的行为是具有误导性的:
isNaN(undefined) // true
_.isNaN
(来自Underscore.js)是一个优雅的函数,其行为符合预期:
// Is the given value `NaN`?
//
// `NaN` is the only value for which `===` is not reflexive.
_.isNaN = function(obj) {
return obj !== obj;
};
_.isNaN(undefined) // false
_.isNaN(0/0) // true
isNaN(undefined)
返回 true
有什么问题吗?因为 undefined
不是数字。你觉得这里有什么会让人误解的地方? - trejderundefined
不是数字的事实。这导致我们得出结论,isNaN(undefined)
应该返回true
。NaN
和undefined
是不同的值和不同的类型,这个事实并不改变我的论点。因为这是完全不同的故事。如果我有错的话,请指出来。 - trejderisNaN(x)
应该等价于 !isNumber(x)
,而我建议它应该告诉我们 x 的值是否确切为 NaN。如果想知道一个值是否不是数字,最好使用 Object.prototype.toString.call(x) !== '[object Number]'
,因为它不允许竞争性解释。 - davidchambersif (x !== x)
并且有信心所有当前和未来的团队成员都能理解它的作用,那太好了。如果不是,那么最好有一个函数来回答这个问题:这个值是否为 NaN? 不幸的是,内置的 isNaN 函数并不是那个函数。 - davidchambers尝试使用Object.is()
,它确定两个值是否为相同的值。如果满足以下条件之一,则两个值是相同的:
undefined
null
true
或都是false
+0
-0
NaN
NaN
,并且都具有相同的值例如:Object.is(NaN, NaN)
=> true
请参阅https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
0 === -0
返回true
,但Object.is(0, -0)
返回false
。对于提问者的用例,您可能需要执行val1 === val2 || Object.is(val1, val2)
。 - Michael Kropatif (val1 === val2)
如果其中一个或两个都是 NaN
,它将被解释为假。
此外,NaN !== NaN
NaN
时返回true。 - Adam Parkin无论比较方法如何,NaN永远不等于自身,因此我能想到的唯一更简洁的解决方案是创建一个具有描述性名称的函数调用,用于执行这种非常特殊的比较,并在代码中使用该比较函数。
这也会有一个优点,即当您决定未定义应该等于未定义时,可以将更改局部化到算法。
if (val1 + '' == val2 + '')
" " == 0;
,这是 true
,但在您的代码中将是 false
。这可能被认为是一种改进。 - user1106925那么Number.isNaN()函数是什么呢?我认为在任何时候都应该尽可能使用它。
> NaN === NaN
false
> Number.isNaN
ƒ isNaN() { [native code] }
> Number.isNaN() === Number.isNaN()
true
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN
if(val1 === val2 || (val1 !== val1 && val2 !== val2))
原因是全局的isNaN
有误。在某些情况下,它会给出错误的结果,例如:
isNaN(undefined); // true
isNaN({}); // true
isNaN("lorem ipsum"); // true
我在这里发布了一份全面的答案,其中还涵盖了NaN相等性的比较。
Number.isNaN()
而不是isNaN()
,因为isNaN()
会尝试将值转换为数字。const areEqual = (a, b) => a === b || (Number.isNaN(a) && Number.isNaN(b));
if (areEqual(val1, val2)) {...}
isNaN()
可能会导致以下问题:let val1 = 'a string';
let val2 = undefined;
let val3 = {};
isNaN(val1) && isNaN(val2) && isNaN(val3); // true
Number.isNaN(val1) && Number.isNaN(val2) && Number.isNaN(val3); // false
isNaN(1n); // Uncaught TypeError: Cannot convert a BigInt value to a number
Number.isNaN(1n); // false
NaN与任何值的比较结果都为False
。
我们可以使用JavaScript函数isNaN()
来检查NaN的相等性。
例如:
1. isNaN(123) //false
2. var array = [3, NaN];
for(var i = 0 ; i< array.length; i++){
if(isNaN(array[i])){
console.log("True ---- Values of " + i);
} else {
console.log("false ---- Values of " + i);
}
}
结果:
假 ---- 值为0
真 ---- 值为1
||
和&&
是非常丑陋和令人困惑的。 - ThiefMasterNaN
和NaN
应该被认为是不相等的,因为例如0/0
和parseInt("not a number!")
虽然它们两个都求值为NaN
,但不应被视为相等。 - Peter Olson