Преобразование скалярных типов при сравнении JavaScript

tekken

Объясните, пожалуйста, почему из трех алертов ниже исполняется только последний? Вроде как во всех трёх случаях идет мягкое сравнение на равенство к true

if (true == "0") alert('Тру равно нулю!');

if ("0" == true) alert('Ноль равен тру');

if ("0") alert('Как бы тоже тру, или как?');

https://jsfiddle.net/z1xbshmk/

2 ответа

tekken

Стоит обратиться к спецификации При вычислении равенства EqualityExpression == RelationalExpression получаются значения левой и правой части, и к ним применяется Abstract Equality Comparison.

Сравнение x == y, где x и y - значения, возвращает <em>true</em> or <em>false</em>. Такое сравнения производится следующим образом: Если <em>Type(x)</em> тот же самый, что и <em>Type(y)</em>, тогда возвращается результат выполнения <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-strict-equality-comparison" target="_blank">Strict Equality Comparison</a> x === y. Если <em>x</em> является <span>null</span> и <em>y</em> является <span>undefined</span>, вернуть <em>true</em>. Если <em>x</em> является <span>undefined</span> и <em>y</em> является <span>null</span>, вернуть <em>true</em>. Если <em>Type(x)</em> - это <span>Number</span> и <em>Type(y)</em> - это <span>String</span>, вернуть результат выражения <em>x == ToNumber(y)</em>. Если <em>Type(x)</em> - это <span>String</span> и <em>Type(y)</em> - это <span>Number</span>, вернуть результат выражения <em>ToNumber(x) == y</em>. Если <em>Type(x)</em> - это <span>Boolean</span>, вернуть результат выражения <em>ToNumber(x) == y</em>. Если <em>Type(y)</em> - это <span>Boolean</span>, вернуть результат выражения <em>x == ToNumber(y)</em>. Если <em>Type(x)</em> один из следующих: <span>String</span>, <span>Number</span>, или <span>Symbol</span> и <em>Type(y)</em> это <span>Object</span>, вернуть значение выражения <em>x == ToPrimitive(y)</em>. Если <em>Type(x)</em> - это <span>Object</span> и <em>Type(y)</em> один из следующих: <span>String</span>, <span>Number</span>, или <span>Symbol</span>, вернуть значение выражения <em>ToPrimitive(x) == y</em>. Вернуть <em>false</em>.

Рассмотрим первый пример:

true == "0"

Это выражении соответствует ветке

Если <em>Type(x)</em> - это <span>Boolean</span>, вернуть результат выражения <em>ToNumber(x) == y</em>.

При приведении к числу получаем выражение: 1 == "0" попадаем в ветку

Если <em>Type(x)</em> - это <span>Number</span> и <em>Type(y)</em> - это <span>String</span>, вернуть результат выражения <em>x == ToNumber(y)</em>.

При приведении к числу получаем выражение: 1 == 0 и как результат: false.

Со вторым случаем происходит аналогичное.

Теперь рассмотрим третий случай.

Обратимся опять к спецификации:

К выражению внутри скобок применяется функция ToBoolean, которая в случае строки возвращает false если строка пустая(длина строки 0), и true - в противном случае.

Так как "0" - не пустая(длина строки 1), то условие считается выполненным.


tekken

  1. Строка таки преобразуется в ноль, что трактуется как ложь.
  2. То же самое, только наоборот аргументы.
  3. Это не пустая строка, трактуется как true.

Как оно происходит.

licensed under cc by-sa 3.0 with attribution.