Почему я использую только === вместо ==?

JavaScript

предисловие

без контактаeslintРаньше формат моего кода, можно сказать, следовал моему настроению, и я мог писать все, что мне нравится. Поскольку три года назад выполнение проекта Vue представилоeslintС тех пор мой код стал более стандартизированным, настолько, что теперь у меня обсессивно-компульсивное расстройство.eslintСуществует множество стандартов для спецификации кода. В основном,ReactКод проекта следуетairbnbТехнические характеристики,VueКод проекта следуетstandardТехнические характеристики. Однако есть правило, в котором упоминается:Всегда используйте === вместо ==. Таким образом, я использовал эту привычку по сей день, но я не углублялся в нее, я только знаю, что это может уменьшить количество неожиданных ошибок в коде. Так как я не смирился с тем, что "знаю, но не знаю почему", хочу рассмотреть поближе===а также==разница.

Разница между === и ==

===а также==Существенная разница заключается в следующем: первое определяет, строго ли равны операнды с обеих сторон оператора, и не выполняется преобразование типа данных; второе — определяет, не являются ли операнды с обеих сторон оператора строго равными. и неявный тип будет выполнен соответствующим образом convert.

== Условия использования

нижеприведенный==При сравнении операторов оба операндаxа такжеyМелкий шрифт для неявных преобразований типов:

1.xа такжеyтого же типа

1.1 Если x неопределенного типа, вернуть true.

console.log(undefined == undefined); // true

1.2 Если x имеет тип null, вернуть true.

console.log(null == null); // true

1.3 Если x имеет тип number, и только один из x и y имеет значение NaN, вернуть false. (NaN не равен самому себе)

console.log(NaN == 0); // false
console.log(0 == NaN); // false
console.log(NaN == 1); // false
console.log(1 == NaN); // false
console.log(NaN == NaN); // false

1.4 Если x имеет тип number и значения x и y равны, вернуть true. Возвращает false, если значения x и y не равны.

console.log(0 == 0); // true
console.log(1 == 1); // true
console.log(0 == 1); // false

1.5 Если x имеет тип number, а значения x и y равны +0 или -0, вернуть true.

console.log(-0 == +0); // true
console.log(+0 == -0); // true
console.log(+0 == +0); // true
console.log(-0 == -0); // true

1.6 Если x имеет тип string, вернуть true тогда и только тогда, когда последовательности символов x и y точно равны. В противном случае вернуть ложь.

console.log('foo' == 'foo'); //true
console.log('foo' == 'bar'); // false

1.7 Если x является логическим типом, когда и x, и y имеют значение true или false, вернуть true. В противном случае вернуть ложь.

console.log(true == true); // true
console.log(false == false); // true
console.log(true == false); // false
console.log(false == true); // false

1.8 Если x имеет тип object, вернуть true тогда и только тогда, когда x и y являются одной и той же ссылкой. В противном случае вернуть ложь.

var x = {}, y = {}, z = x;
console.log(x == y); // false
console.log(x == z); // true
console.log(y == z); // false
console.log(x == {}); // false
console.log({} == y); // false
console.log({} == {}); // false

2.xа такжеyне тот тип

2.1 Если x равно null, а y не определено, или если x не определено, а y равно null, вернуть true.

console.log(null == undefined); // true
console.log(undefined == null); // true

2.2 Если один из x и y имеет тип число, а другой тип строка, сначала неявно преобразуйте тип строка в число, а затем выполните числовое сравнение.

console.log('123' == 123); // true  <=> Number('123') == 123  <=> 123 == 123
console.log(123 == '123'); // true  <=> 123 == Number('123')  <=> 123 == 123
console.log('abc' == 123) // false  <=> Number('abc') == 123  <=> NaN == 123

2.3 Если существуют и x, и y, то при наличии логического типа логический тип неявно преобразуется в числовой тип, а затем выполняется численное сравнение.

console.log(false == 0); // true  <=>  Number(false) == 0  <=>  0 == 0
console.log(true == 1); // true  <=>  Number(true) == 1 <=>  1 == 1
console.log(false == 2); // false  <=>  Number(false) == 2  <=> 0 == 2
console.log(true == 2); // false  <=>  Number(true) == 2  <=> 1 == 2

2.4 Если x и y оба, один из них является типом числа, типом строки или логическим типом, а другой является типом объекта, тип объекта будет вызываться неявно.valueOfилиtoStringметод, а затем сравните.

var foo = { bar: 0 };
console.log(foo == 2); // false <=> foo.toString() == 2 <=> '[object Object]' == 2  <=> Number('[object Object]') == 2  <=> NaN == 2
console.log(foo == '2'); // false <=> foo.toString() == '2' <=> '[object Object]' == '2'
console.log(foo == '[object Object]'); // true

ps: мы можем переопределить метод valueOf или toString, чтобы переопределить поведение собственного метода по умолчанию для достижения наилучшего эффекта контраста.

var foo = { bar: 0 };
foo.toString = () => '2'; // foo.valueOf = () => 2; 若两者都重写了,以valueOf为准
console.log(foo == 2); // true;
console.log(foo == '2'); // true

2.5 Вернуть false в остальных случаях.

console.log('123abc' == 123); // false
console.log(null == false); // false
console.log(undefined == false); // false
...

Далее обсудим интересную тему:[] == ![] // -> true, используя детали, перечисленные выше, выводим шаг за шагом.

// ![]返回是一个boolean类型 -> !Boolean([]) -> !true -> false
[] == ![]  <=> [] == false
// object类型和boolean对比,先转换对象 ->  [] -> [].toString() -> ''
[] == false <=> '' == false
// ==两边操作数出现boolean类型,我们先将它做数字类型转换 -> false -> Number(false) -> 0
'' == false <=> '' == 0
// ==两边操作数出现string类型和number类型,我们先将string类型做数字类型转换 -> '' -> Number('') -> 0
'' == 0 <=> 0 == 0
// 所以最后得出的结果为 true。

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

=== Условия использования

Далее, давайте посмотрим, используя===Детали , где x и y также используются для представления операндов с обеих сторон оператора.

  • Если типы x и y различны, возвращайте false напрямую.
console.log(undefined === null); // false
console.log(1 === true); // false
console.log(0 === false); // false
console.log(1 === '1'); // false
console.log(0 === '0'); // false
console.log('1' === true); // false
console.log('0' === false); // false
console.log(0 === []); // false
console.log(false === []); // false
console.log('' === []); // false
  • Если x и y одного типа, если они оба являются базовыми типами, сравните, равны ли их значения; если они являются ссылочными типами, сравните, являются ли два ссылочных адреса одним и тем же адресом.
var a = {}, b = {}, c = a;
console.log(undefined === undefined); // true
console.log(null === null); // true
console.log(0 === 0); // true
console.log(0 === 1); // false
console.log('0' === '0'); // true
console.log('0' === '1'); false
console.log(false === false); // true;
console.log(true === false); // false
console.log({} === {}); // false
console.log(a === b); // false
console.log(a === c); // true;
console.log(b === c); // false
...

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