Ответ 1
![]
оценивается как false
, потому что ссылка является правдой. []
может быть преобразован в число (0 в этом случае), которое является ложным. Поэтому: условие проходит как равное. Если вы сделали ===
, это было бы неверно.
Я бы точно знал, почему выражение, указанное в заголовке
[] == ![]
оценивается как true.
Вы не можете сравнивать массивы как строки. Я понимаю. Если
[] == []
будет оцениваться как false, потому что ссылки разные. Хотя, если у нас есть следующее утверждение.
var arr = [];
arr == arr // this evaluates to true simply because references are the same.
Чтобы A == B вернул true, либо A, либо B должны быть ложными или истинными. A ==! B, чтобы вернуть true A, может быть истинным, а B может быть ложным или наоборот, но в этом случае A и B являются одинаковыми значениями, поэтому я не получаю его.
![]
оценивается как false
, потому что ссылка является правдой. []
может быть преобразован в число (0 в этом случае), которое является ложным. Поэтому: условие проходит как равное. Если вы сделали ===
, это было бы неверно.
В основном Javascript пытается преобразовать обе стороны в число, если оба типа не совпадают. И если его Object, он пытается преобразовать в примитивное значение
Итак, в этом случае шаг за шагом будет
=> []==![]
=> []==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
Можно проверить объяснение ecmascript здесь в описании компилятора http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3
Вот более подробное объяснение от codementor.io
Прежде чем понять, что происходит, нам нужно понять концепцию правды и ложности в JavaScript и как! (логический NOT). Значения, такие как false, null, undefined, NaN, 0, '' and ""
, считаются ложными.
Другие значения, такие как *true, {}, [], "foo"
* и т.д., Считаются правдивыми.
! оператор, с другой стороны, определяется только для булевых значений.
Любой другой тип данных будет автоматически принудительно влечет за собой соответствующее логическое значение при работе с! оператор.
Здесь ![]
оценивается как false, и сравнение фактически становится '[] == false'
, которое оценивается как 'true'
.
Разве это не должно быть ложным, так как пустые массивы правдивы?
Это право, но оператор с двойным равным вычисляет выражения для определенных правил.
Мы пытаемся сравнить объект с логическим значением, и JavaScript будет неявно преобразовывать операнды в тип Number. Number([]) is 0
и Number(false) is also 0
, который оценивается как true since zero is equal to zero
Всякий раз, когда 2 значения сравниваются с использованием ==, javascript выполняет Алгоритм сравнения абстрактного равенства.
Здесь x is [], а y is! []. Кроме того,
typeof([]) // "object"
typeof(![]) // "boolean"
Так как y является булевым, а x является объектом, условие 7 является первым:
Если тип (y) булев, верните результат сравнения x == ToNumber (у).
Каково значение ToNumber (y)?
Number(![]) // 0
потому что [] является правдивым значением, отрицание делает его ложным. Число (false) равно 0
Теперь мы имеем сравнение: [] == 0.
Так как typeof (0) является "числом", то теперь выполняется условие 8:
Если Type (x) - это Object и Type (y) - либо String или Number, return результат сравнения 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. Я думаю, вы можете взять, если отсюда:)
читайте о Абстрактное сравнение равенства по спецификациям!
Array - это специальный объект в javascript, который можно сравнить с пользовательскими объектами. Даже это тип - объекты, [] instanceof Array == true;
используя var x = []; совсем не похож на вызов Array contructor. И сравнение двух экземпляров объектов в javascript вернет false, потому что они не используют один и тот же адрес памяти. Это похоже на сравнение указателей.