Большинство программистов на JavaScript знают, что «нормального» равенства (==) следует избегать в пользу строгого равенства (===)
[1] . Тем не менее, время от времени вам нужно что-то даже более строгое, чем ===: если вы хотите проверить наличие NaN или хотите различить -0 и +0. В этом посте рассказывается о деталях и решении ECMAScript.next
[2] — операторе «есть».
Проверка на NaN
NaN не является строго равным самому себе, нарушая основной закон рефлексивности: в математике любое значение x всегда равно себе:
x = x
Этот закон не распространяется на === и NaN:
> NaN === NaN false
Как следствие, вы не можете найти NaN в массивах через indexOf, потому что этот метод опирается на ===, чтобы определить, какие элементы массива равны его первому аргументу:
> [ NaN ].indexOf(NaN) -1
Если вы не можете использовать === для проверки на NaN, какова альтернатива? Существует глобальная функция isNaN (), но она проблематична, потому что она преобразует свой аргумент в число и, таким образом, возвращает true для многих значений, которые явно не являются NaN [3] :
> isNaN("foo") true
Пояснение: «foo», преобразованный в число, является NaN.
> Number("foo") NaN
Одним из способов обнаружения NaN является использование того факта, что это единственное значение, которое не является строго равным самому себе:
function myIsNaN(value) { return value !== value; }
Более понятная альтернатива — использовать isNaN () после проверки, является ли значение числом. Это позволяет избежать проблемного преобразования не чисел [3] .
function myIsNaN2(value) { return typeof value === 'number' && isNaN(value); }
ECMAScript.next будет иметь Number.isNaN (), фиксированную версию глобального isNaN ().
Различают между -0 и +0
Этот вариант использования встречается редко, но иногда вы можете захотеть различить -0 и +0, которые являются различными значениями в JavaScript. === не позволяет вам сделать это:
> -0 === +0 true
Как вы можете сделать различие? Оказывается, есть одно число, которое вы можете разделить на 0 — число 1. Деление 1 на -0 приводит к -Infinity, а деление его на +0 приводит к бесконечности. И эти две бесконечности можно различить по ===:
> 1 / -0 -Infinity > 1 / +0 Infinity > Infinity === -Infinity false
Более строгое равенство в ECMAScript.next: оператор «is»
ECMAScript.next будет иметь оператор
«is», который выполняет «более строгое равенство»: он считает NaN равным самому себе и различает -0 и +0. Его отрицание называется «нет». Примеры:
> NaN is NaN true > -0 isnt +0 true
Оператор дополняется функцией Object.is (), которую можно перенести обратно в более старые версии ECMAScript. В этих версиях это можно реализовать следующим образом (слегка отредактированная версия предложения ECMAScript.next ):
Object.is = function(x, y) { if (x === y) { // x === 0 => compare via infinity trick return x !== 0 || (1/x === 1/y); } // x !== y => return true only if both x and y are NaN return x !== x && y !== y; };
Почему в предложении ECMAScript.next используется название «egal»?
Причина, по которой в
предложении ECMAScript.next используется имя «egal» для оператора «is», связана с оригинальным документом о равенстве: «
Равные права для функциональных объектов или, чем больше вещи меняются, тем больше они одинаковы » Генри Г. Бейкер, 1990. Цитируя объяснение этой статьи о том, что его оператор равенства называется «egal»:
Egal — устаревший норманнский термин для равных, а Egalité — французское слово для социального равенства.
Попробовать Object.is ()
Если вы хотите попробовать Object.is (), вы можете использовать es6-shim
[4], который переносит часть ECMAScript.next (который является текущим кодовым именем для ECMAScript 6) в ECMAScript 5.
Рекомендации
- Равенство в JavaScript: === против ==
- ECMAScript.next: обновление «TXJS» от Eich
- NaN и Бесконечность в JavaScript
- es6-shim — функциональность ECMAScript 6 в ECMAScript 5