В чем разница между (НАН!= НАН) и (НАН!= = НАН)?



прежде всего я хочу отметить, что я знаю, как isNaN() и Number.isNaN() работа. Я читаю Определенное Руководство Дэвид Фланаган и он дает пример того, как проверить, если значение NaN:



x !== x


в результате true, если и только если x и NaN.



но теперь у меня есть вопрос: почему он использует строгое сравнение? Потому что кажется, что



x != x


ведет себя точно так же. Безопасно ли использовать оба версии, или мне не хватает некоторых значений в JavaScript, которые будут возвращать true на x !== x и false на x != x?

1189   5  

5 ответов:

во-первых, позвольте мне отметить, что NaN Это очень особое значение: по определению, оно не равно самому себе. Это исходит из стандарта IEEE-754, на котором основаны номера JavaScript. Значение "not a number" никогда не равно самому себе, даже если биты точно совпадают. (Которые они не обязательно находятся в IEEE-754, это позволяет использовать несколько разных значений "не число".) Вот почему это даже возникает; все остальные значения в JavaScript равны сами себе,NaN - Это просто специальный.

...я пропустил какое-то значение в JavaScript, которое вернет true для x != = x и false для x != x?

нет, это не так. Единственная разница между !== и != заключается в том, что последний будет выполнять приведение типа, если необходимо, чтобы типы операндов были одинаковыми. В x != x, типы операндов одинаковы, и поэтому это точно так же, как x !== x.

это ясно с самого начала определение Абстрактная Операция Равенства:

  1. ReturnIfAbrupt (x).
  2. ReturnIfAbrupt (y).
  3. если тип (x) совпадает с типом(y), то

    возвращает результат выполнения строгого сравнения равенства x === y.

  4. ...

первые два шага являются основными сантехника. Таким образом, по сути, самый первый шаг == чтобы увидеть, если типы одинаковы, и, если да, то делать === вместо. != и !== это просто отрицаемые версии этого.

так что если Фланаган прав, то только NaN даст истину для x !== x, мы можем быть уверены, что это также верно, что только NaN даст истину для x != x.

многие программисты JavaScript по умолчанию используют === и !== чтобы избежать некоторых подводных камней вокруг типа принуждения свободные операторы делают, но нет ничего, чтобы прочитайте использование Фланаганом строгого и свободного оператора в этом случае.

для целей NaN,!= и !== сделать то же самое.

однако, многие программисты избегают == или != в JavaScript. Например, Дуглас Крокфорд считает их среди "плохое " языка JavaScript, потому что они ведут себя неожиданным и запутанным образом:

JavaScript имеет два набора операторов равенства: === и !==, и их злые Близнецы == и !=. Хорошие из них работают так можно было бы ожидать.

...мой совет-никогда не использовать злых близнецов. Вместо этого, всегда используйте === и !==.

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

Object.defineProperty(
  self,
  'x',
  { get: function() { return self.y = self.y ? 0 : '0'; } }
);

затем у нас есть

x != x // false

но

x !== x // true

Я просто хочу указать NaN это не единственное, что производит x !== x без использования глобального объекта. Есть много умных способов вызвать такое поведение. Вот один с помощью геттеров:

var i = 0, obj = { get x() { return i++; }};
with(obj) // force dynamic context, this is evil. 
console.log(x === x); // false

как указывают другие ответы,== выполняет тип coersion, но в как и в других языках и par стандарт - NaN указывает на сбой вычисления, и по уважительным причинам не равен себе.

по некоторым причинам, не зависящим от меня людям ocnsider это проблема с JS но большинство языков, которые имеют двойники (а именно, C, Java, C++, C#, Python и другие) демонстрируют это точное поведение, и люди просто в порядке с ним.

как иногда, изображения лучше, чем слова, проверьте это стол (что является причиной для меня, чтобы сделать это ответ вместо комментария, потому что он получает лучшую видимость).

там вы можете видеть, что строгое сравнение равенства ( = = = ) возвращает true только в том случае, если тип и содержимое совпадают, поэтому

var f = "-1" === -1; //false

в то время как абстрактное сравнение равенства ( = = ) проверяет только содержание* путем преобразования типов, а затем строго сравнивая их:

var t = "-1" == -1; //true

хотя это не понятно, без консультации ECMA, что JavaScript учитывает при сравнении, таким образом, что приведенный ниже код оценивает в true.

 var howAmISupposedToKnowThat = [] == false; //true

Comments

    Ничего не найдено.