[] ==![] оценивается как истинное

Я хотел бы знать, почему выражение, данное в заголовке

[] == ![]

оценивается в 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

Ваше понимание верно, но вы упустили это! Оператор запрашивает явное приведение пустого массива к логическому.

Шаги в [] ==![]

  1. Явное приведение правого выражения к логическому выражению с помощью! оператор. Итак, [] становится ложным.
  2. Теперь действие оператора ==. Так как один из них логический (ложь в правой части оператора ==). который будет приведен к номеру.
  3. Где as [] будет приведен к Number, который 0.

Так что 0 == 0, что правда.

Массив - это специальный объект в javascript, который можно сравнить с пользовательскими объектами. Даже его тип - объекты, [] instanceof Array == true;

так что используя var x = []; это почти то же самое, что вызывать конструктор Array. И сравнение двух экземпляров объектов в javascript вернет false, потому что они не используют один и тот же адрес памяти. Это как сравнение указателей.

Другие вопросы по тегам