[] ==![] оценивается как истинное
Я хотел бы знать, почему выражение, данное в заголовке
[] == ![]
оценивается в true
,
Вы не можете сравнивать массивы как строки. Я понимаю. Если
[] == []
будет оцениваться как ложный, потому что ссылки разные. Хотя, если у нас есть следующее утверждение.
var arr = [];
arr == arr // this evaluates to true simply because references are the same.
Для того чтобы A == B вернуть true
либо А и В должны быть false
или же true
, A ==!B, чтобы вернуться true
А может быть true
и B может быть false
или наоборот, но в этом случае A и B являются одинаковыми значениями, поэтому я не понимаю.
6 ответов
![]
оценивает false
потому что ссылка правдива. []
может быть преобразовано в число (0 в данном случае), которое является ложным. Следовательно: условие проходит как равное. Если вы сделали ===
это было бы ложно.
По сути, Javascript пытается преобразовать обе стороны в число, если оба типа не совпадают. И если это объект, он пытается преобразовать в примитивное значение
Так что в этом случае шаг за шагом будет
=> []==![]
=> []==false // Type conversion by the statement itself
=> []==0 // To number of right operand
=> ""==0 // To Primitive call for Array which will in this case convert to empty string
=> 0==0 // To number call of "" which is 0
=> true
Найти объяснение экмаскрипта можно здесь, в описании компилятора http://www.ecma-international.org/ecma-262/5.1/
Всякий раз, когда 2 значения сравниваются с использованием ==, javascript выполняет алгоритм сравнения абстрактного равенства.
Здесь x - это [], а y -![]. Также,
typeof([]) // "object"
typeof(![]) // "boolean"
Поскольку у - логическое значение, а х - объект, условие 7 выполняется первым:
Если Type (y) - Boolean, вернуть результат сравнения x == ToNumber(y).
Каково значение ToNumber(y)?
Number(![]) // 0
поскольку [] является истинным значением, отрицание делает его ложным. Число (ложь) равно 0
Теперь у нас есть сравнение: [] == 0.
Поскольку typeof(0) является "числом", условие 8 теперь выполняется:
Если Type(x) равен Object, а Type (y) является либо String, либо Number, вернуть результат сравнения ToPrimitive (x) == y.
ToPrimitve (x) похож на x.toString().
[].toString() // ”” - the empty string
Почти готово, теперь мы сталкиваемся со сравнением: "" == 0
Теперь условие 5 выполняется:
Если Type(x) равен String, а Type (y) равен Number, вернуть результат сравнения ToNumber(x) == y.
ToNumber(“”) // 0
Наконец, оба операнда имеют одинаковый тип и выполняется условие 1. Я думаю, что вы можете взять, если отсюда:)
Читайте о Сравнении абстрактного равенства по спецификациям!
Вот более подробное объяснение от codementor.io
Прежде чем понять, что происходит, нам нужно понять концепцию правдивости и ложности в JavaScript и как! (логическое НЕ) оператор работает. Значения, такие как false, null, undefined, NaN, 0, '' and ""
считаются ложными. Другие значения, такие как *true, {}, [], "foo"
* и т. д. считаются правдивыми.! Оператор, с другой стороны, определен только для логических значений. Любой другой тип данных будет автоматически приведен к соответствующему логическому значению при работе с! оператор. Вот, ![]
оценивается как ложное, и сравнение фактически становится '[] == false'
который оценивает 'true'
, Разве это не должно быть ложным, поскольку пустые массивы правдивы? Это верно, но оператор двойного равенства вычисляет выражения по определенным правилам. Мы пытаемся сравнить объект с логическим значением, и JavaScript неявно преобразует операнды в тип Number. Number([]) is 0
а также Number(false) is also 0
, который оценивает true since zero is equal to zero
Ваше понимание верно, но вы упустили это! Оператор запрашивает явное приведение пустого массива к логическому.
Шаги в [] ==![]
- Явное приведение правого выражения к логическому выражению с помощью! оператор. Итак, [] становится ложным.
- Теперь действие оператора ==. Так как один из них логический (ложь в правой части оператора ==). который будет приведен к номеру.
- Где as [] будет приведен к Number, который 0.
Так что 0 == 0, что правда.
Массив - это специальный объект в javascript, который можно сравнить с пользовательскими объектами. Даже его тип - объекты, [] instanceof Array == true;
так что используя var x = []; это почти то же самое, что вызывать конструктор Array. И сравнение двух экземпляров объектов в javascript вернет false, потому что они не используют один и тот же адрес памяти. Это как сравнение указателей.