Разберитесь с запутанными отношениями между равенством (==) и конгруэнтностью (===) в JS

внешний интерфейс JavaScript регулярное выражение

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

Прежде всего объясняются два отношения: равное не обязательно равно, конгруэнтное должно быть равным, неравное не должно быть равным, не конгруэнтное не обязательно не равно. В статье, где можно использовать конгруэнтность, она должна быть установлена, а где она не установлена, конгруэнтность не должна устанавливаться, я думаю, это всем понятно, и никаких специальных объяснений делаться не будет.

Судя по знаку 0

0 === -0Но они не идентичны, как судить?

Рассмотрим несколько отношений:

Infinity === Infinity // true
Infinity === -Infinity // false
1/-0 === -Infinity // true
1/0 === Infinity // true

Итак, есть:

1/-0 === 1/-0 // true
1/0 === 1/0 // true
1/-0 === 1/0 //false

Следовательно, 0 на самом деле является знаковым и может быть оценен с помощью вышеописанных методов.

судитьundefinedа такжеnull

undefined === undefined // true
null === null // true
null == undefined // true
null === undefined // false

nullИли никакие переменные не определены, просто используйте "==", но если вы хотите четкоnullа такжеundefined, Это должно было бы больше сравнить. Вот два анализаnullа такжеundefinedМетоды:

Object.prototype.toString.call(null) === "[object, Null]"
Object.prototype.toString.call(undefined) === "[object, Undefined]"

// 还有一个关系注意一下,我看有些面试题会问到:
typeof null === "object"
typeof undefined === "undefined"

Оценка регулярных выражений

Два одинаковых регулярных выражения не равны:

var a = /[1-9]/;
var b = /[1-9]/;
a == b // false

Поскольку A и B на самом деле на самом деле два объекта регулярного выражения, которые также имеют тип ссылочного типа:

typeof a === "object" // true
typeof b === "object" // true

Если мы хотим сравнить содержимое двух регулярных выражений, но не заботимся об адресах памяти, нужно только сравнить, равны ли две строки выражения:

var a = /[1-9]/;
var b = /[1-9]/;
'' + a === '' + b // true
注:'' + /[1-9]/ === '/[1-9]/'

сравнение строк

Мы должны различать строки символов объектов с
Если это строка, напрямую используйте "===” для оценки:

var a = 'a string';
var b = 'a string';
a === b //true

Однако для строковых объектов (ссылочных типов) при прямом сравнении сравнивается по-прежнему адрес памяти:

var a = new String('a string');
var b = new String('a string');
a == b // false

Если вам важно, одинаково ли содержимое строк, вы можете преобразовать строковые объекты в строки и сравнить их:

var a = new String('a string');
var b = new String('a string');
'' + a == '' + b // true

// 也可以使用toString方法比较:
a.toString() === b.toString() // true

Следовательно, самый надежный способ определить, является ли содержимое двух строк одинаковым:

function isStringEqual(a, b) {
    return '' + a === '' + b;
}

сравнение чисел

Также необходимо различать числовые значения и числовые объекты:

var a = new Number(5);
var b = new Number(5);

// 直接对比时不相等
a == b //false

// 使用+符号,转化成数值的对比
+a === +b //true

Тем не менее, есть одно особое значение, которое должно относиться специально, а именноNaN,это такжеNumberТип

Object.prototype.toString.call(NaN) // "[object Number]"
typeof NaN // "number"

Между тем, это приводит к следующим отношениям, определяется ли значением, равное вышеуказанному методу, возникает исключение:

NaN == NaN //false
+NaN == +NaN // false
注:+NaN还是NaN

NaNВ случае судей оба равно этому? Посмотрите на предложение: для любого неNaNчисловой объект или числовое значение (a),+a === +aвсегда держит, если уравнение не удерживает, то естьNaN. Итак, если известно, чтоNaN, как b такжеNaNКогда вы хотите судить, что они равны?

if(+a !== +a) return +b !== +b;

Объяснение следующее:

Предположим, чтоNaN, Условия оценки устанавливаются, если B такжеNaN, выражение оператора return имеет место, returntrue, что указывает на то, что оба равны (обаNaN); если б неNaN, выражение оператора return не выполняется, returnfalse, что указывает на то, что они не равны.

Логика вышеуказанного суждения интегрирована в функцию суждения, а именно:

function isNumberEqual(a, b) {
    if (+a !== +a) return +b !== +b; // 处理特殊情况
    return +a === +b;
}

Сравнение объектов даты

Сравнение объектов не может быть напрямую оценено на равный знак. Мы все еще заботимся о том, только ли только значения даты одинаковы. Поэтому преобразуйте даты в миллисекундные значения, а затем сравните, являются ли значения одинаковыми.

var a = new Date('2017-9-7');
var b = new Date('2017-9-7');
a == b //false
+a === +b //true
注:+a的值为1504713600000,即,对应2017.9.7 00:00:00的毫秒数

效果和使用getTime()方法对比一样
a.getTime() === b.getTime() // true

Логическое сравнение объектов

Объекты нельзя сравнивать напрямую, поэтому преобразуйте логическое значение в числовое значение, а затем сравните

var a = new Boolean('123');
var b = new Boolean('123');
a == b //false
+a === +b //true
// 注: 布尔值为真,前面加“+”,转化为数值1,为假则转为0

Для многих методов сравнения в этой статье вы действительно можете найти соответствующий объектный метод для достижения сравнения значений.Главное в этой статье - напомнить вам, что при сравнении обращайте внимание на то, чтобы различать, является ли сравнение значением или объектом. Если цель состоит в том, чтобы сравнить, равны ли значения, необходимо дальнейшее преобразование. Кроме того, обратите особое внимание на особые случаи, которые существуют при сравнении значений каждого типа, а также на взаимосвязь между особыми значениями.

Выше, я надеюсь, это полезно для вас.欢迎留言纠错或补充。