Сравнение значений NaN на равенство в Javascript - PullRequest
59 голосов
/ 23 января 2012

Мне нужно сравнить два числовых значения на равенство в Javascript.Значения также могут быть NaN.Я придумал этот код:

if (val1 == val2 || isNaN(val1) && isNaN(val2)) ...

, который работает нормально, но мне он кажется раздутым.Я хотел бы сделать это более кратким.Есть идеи?

Ответы [ 12 ]

51 голосов
/ 23 января 2012
if(val1 == val2 || (isNaN(val1) && isNaN(val2)))

Ничего не улучшается.Просто добавьте скобки, чтобы всем было понятно.

23 голосов
/ 23 января 2012

Избегайте 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
5 голосов
/ 17 января 2018

Попробуйте использовать 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

5 голосов
/ 23 января 2012

Пока вы знаете, что эти две переменные являются числовыми, вы можете попробовать:

if (val1 + '' == val2 + '')

Превращает два значения в строки. Забавный ответ, но это должно сработать. :)

5 голосов
/ 23 января 2012

NaN никогда не бывает равным самому себе, независимо от метода сравнения, поэтому единственное более краткое решение для вашей проблемы, о котором я могу подумать, - это создать вызов функции с описательным именем для выполнения этого довольно специального сравнения и использовать это сравнение вместо этого используйте функцию в вашем коде.

Это также имело бы преимущество локализации изменений в алгоритме в тот день, когда вы решили, что undefined также должен быть равен undefined.

5 голосов
/ 23 января 2012

if ( val1 === val2 )

Если один из них или оба равны NaN, значение будет равно false.

Также NaN !== NaN

2 голосов
/ 21 августа 2015

Для числовых случаев решение подходит, но для расширения его работы и для других типов данных мое предложение будет следующим:

if(val1 === val2 || (val1 !== val1 && val2 !== val2))

Причина глобальна isNaN ошибочна. Это даст вам неправильные результаты в сценариях, таких как

isNaN(undefined); // true
isNaN({});        // true
isNaN("lorem ipsum"); // true 

Я разместил здесь исчерпывающий ответ, который также охватывает сравнение NaN на равенство.

Как проверить, является ли переменная JavaScript NaN

2 голосов
/ 17 июня 2015

А что насчет функции 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

1 голос
/ 03 мая 2013

Я создал этот ответ после рассмотрения предложений ThiefMaster, Esailija, Joachim Isaksson и davidchambers. Можно ли это еще улучшить?

// Determines if two numeric values are equal.
// Also returns true when both parameters are NaN.
function areEqualNumeric(val1, val2) {
    return val1 === val2 || (val1 !== val1 && val2 !== val2);
}
0 голосов
/ 19 мая 2017

Найден другой способ с использованием Array.prototype.includes MDN link .По-видимому, [NaN] .includes (NaN) возвращает true для NaN.

function IsActuallyNaN(obj) {
  return [obj].includes(NaN);  
}

Или мы можем пойти с решением Дэвидхемберса, которое намного проще.

function IsActuallyNaN2(obj) {
  return obj !== obj;
}
...