Ответ 1
Позвольте получить техническую информацию. Я объясню логику цитатами из ECMAScript Standard 262.
Выражение [] ? 1 : 2
очень просто:
11.12 Условный оператор (?:)
- Пусть lref является результатом оценки LogicalORExpression.
- Если ToBoolean (GetValue (lref)) - true, тогда
- Пусть trueRef будет результатом вычисления первого выражения AssignmentExpression.
- Возвращает GetValue (trueRef).
- Else
- Пусть falseRef является результатом вычисления второго выражения AssignmentExpression.
- Возврат GetValue (falseRef)
9.2 ToBoolean
- Undefined: false
- Null: false
- Boolean: результат равен входному аргументу (без преобразования).
- Число: результат равен false, если аргумент равен +0, 0 или NaN; иначе результат будет правдой.
- String: результат неверен, если аргументом является пустая строка (ее длина равна нулю); в противном случае результат верен.
- Объект: true
Итак, это правда.
Теперь для дикой езды, что происходит, когда вы используете оператор double equals. Возможно, это поможет объяснить, почему вы никогда не должны этого делать.
Поведение == объясняется в разделе 11.9.3: Алгоритм сравнения абстрактного равенства.
Для x == y, где x = [] и y = false, это происходит:
11.9.3: Алгоритм сравнения абстрактного равенства
Если тип (y) является логическим, верните результат сравнения x == ToNumber (y)
9.3 ToNumber
Результат +0, если аргумент равен ложь.
Теперь мы имеем [] == 0
11.9.3: Алгоритм сравнения абстрактного равенства
Если Type (x) - это Object и Type (y) - либо String или Number, return результат сравнения ToPrimitive (x) == y.
9.1 ToPrimitive
Возвращает значение по умолчанию для объекта. Значение по умолчанию для объекта извлекается путем вызова внутреннего метода [[DefaultValue]]объект, передавая необязательный подсказку PreferredType. Поведение внутренний метод [[DefaultValue]] определяется этой спецификацией для всех собственных объектов ECMAScript в 8.12.8.
8.12.8 DefaultValue:
Когда внутренний метод O [[DefaultValue]] вызван без намек, тогда он ведет себя так, как будто подсказка Число
- Пусть valueOf является результатом вызова внутреннего метода [[Get]] объекта O с аргументом "valueOf".
- Если IsCallable (valueOf) истинно, тогда,
- Пусть val является результатом вызова внутреннего метода [[Call]] значенияOf, с O в качестве этого значения и пустым списком аргументов.
- Если val является примитивным значением, верните val
- Пусть toString является результатом вызова внутреннего метода объекта [[Get]] объекта O с аргументом "toString".
- Если IsCallable (toString) истинно, тогда,
- Пусть str является результатом вызова внутреннего метода [[Call]] toString, с O как это значение и пустым списком аргументов.
- Если str является примитивным значением, return str.
Я предполагаю, что это первые попытки valueOf, а затем отклоняет его, потому что результатом является тот же массив, с которого вы начали. Затем он вызывает toString в массиве, который, как представляется, универсально реализуется как список значений, разделенных запятыми. Для пустых массивов, подобных этой, это приводит к пустой строке.
Теперь мы имеем '' == 0
11.9.3: Алгоритм сравнения абстрактного равенства
Если Type (x) - String, а Type (y) - Number, верните результат сравнение ToNumber (x) == y
9.3.1 ToNumber Применяется к типу строки
StringNumericLiteral, пустой или содержит только пробел, является преобразован в +0.
Теперь мы имеем 0 == 0
11.9.3: Алгоритм сравнения абстрактного равенства
Если x - это то же числовое значение, что и y, верните true
Высокий. Это правда. Довольно запутанный способ добраться сюда.