JavaScript
Почему в js масив равен не масиву ?
Почему в js []==![] ?
Разные экземпляры массива. Массивы, как и любые другие объекты, не являющиеся примитивами, сравниваются по ссылке, а не по значению.
Amangol Ahmetcafin
Это не имеет никакого отношения к заданному вопросу, поскольку сравниваются не экземпляры, ведь второй операнд имплицитно преобразован в boolean с последующей негацией.

По той же причине, что ![] === ![] (и с нестрогим равенством тоже) будет true.
Ведь сравниваются тут уже вовсе не массивы, а результаты приведения массивов к примитивам.
Запишем твое выражение как ![] == []. Так будет легче объяснять последовательно.
При приведении в boolean работает достаточно простое правило: всё, что не пустая строка, 0, -0, NaN, null, undefined и false, будет преобразовано в true.
Из сказанного выше следует, что массив (и пустой тоже) это true (как и любой другой объект). Здесь происходит не просто преобразование в boolean, а инвертирование такого преобразования (из-за одного оператора отрицания !), поэтому получается false.
И сравнение выглядит теперь так: false == []. Здесь же второй операнд (пустой массив) преобразуется в примитив: поскольку valueOf для любого массива вернет его же (this), тогда для массива вызовется toString, а это эквивалентно вызову метода join(',') у этого массива.
Теперь сравнение выглядит как false == ''. При нестрогом сравнении оба операнда будут преобразованы в number, то есть произойдет имплицитное Number(false) == Number(''). Поскольку оба значения falsy (см. 3 абзаца выше), то оба значения по правилам приведения в число станут 0.
В итоге мы имеем сравнение 0 == 0, что безусловно true. Вот и ответ на твой вопрос, почему в твоем выражении присутствует равенство между операндами.
Кстати, если немного поменять твоё выражение: ![] == ['a'], то равенство не сохранится, поскольку сравнение будет выглядеть (пропуская самые первые шаги) false == 'a', поскольку второй операнд строка, и строка не пустая, то это не falsy значение, и в итоге будет сравнение 0 == 1, что по очевидным причинам false.
Ведь сравниваются тут уже вовсе не массивы, а результаты приведения массивов к примитивам.
Запишем твое выражение как ![] == []. Так будет легче объяснять последовательно.
При приведении в boolean работает достаточно простое правило: всё, что не пустая строка, 0, -0, NaN, null, undefined и false, будет преобразовано в true.
Из сказанного выше следует, что массив (и пустой тоже) это true (как и любой другой объект). Здесь происходит не просто преобразование в boolean, а инвертирование такого преобразования (из-за одного оператора отрицания !), поэтому получается false.
И сравнение выглядит теперь так: false == []. Здесь же второй операнд (пустой массив) преобразуется в примитив: поскольку valueOf для любого массива вернет его же (this), тогда для массива вызовется toString, а это эквивалентно вызову метода join(',') у этого массива.
Теперь сравнение выглядит как false == ''. При нестрогом сравнении оба операнда будут преобразованы в number, то есть произойдет имплицитное Number(false) == Number(''). Поскольку оба значения falsy (см. 3 абзаца выше), то оба значения по правилам приведения в число станут 0.
В итоге мы имеем сравнение 0 == 0, что безусловно true. Вот и ответ на твой вопрос, почему в твоем выражении присутствует равенство между операндами.
Кстати, если немного поменять твоё выражение: ![] == ['a'], то равенство не сохранится, поскольку сравнение будет выглядеть (пропуская самые первые шаги) false == 'a', поскольку второй операнд строка, и строка не пустая, то это не falsy значение, и в итоге будет сравнение 0 == 1, что по очевидным причинам false.
Тут работает приведение типов. Если смотреть ![] == [] // вернут false
[] == ![] // вернет true
а также
[] == null // вернут true
[] == false // вернет true.
правая часть преобразуется в пустой массив, а пусть массив будет равен пустому массиву
[] == ![] // вернет true
а также
[] == null // вернут true
[] == false // вернет true.
правая часть преобразуется в пустой массив, а пусть массив будет равен пустому массиву
Хаял Бабаев
Операция сравнения коммутативна, от перемены мест её операндов результат никак не поменяется.
![] == [] // true
[] == ![] // true
![] == [] // true
[] == ![] // true
Похожие вопросы
- Почему в JS нет низкоуровневых ошибок (предупреждений)?
- Помогите с кодом JS. Как в данном случае вывести сообщение о равных числах?
- Почему jQuery методы популярнее js методов при общении с ДоМ?
- ПОЧЕМУ JS ТАКОЙ НЕПОНЯТНЫЙ???
- Помогите определиться с выбором нового языка (JS(TS) vs Java)
- почему так много js файлов?
- Js фреймворки, что полезного можно для себя найти?
- В чем цель фреймворков js web?
- [HTML/CSS/JS] Как сохранять изменённые в .js данные оффлайн-сервера локально?
- Почему иногда в вакансиях пишут "знания JavaScript или JQuery"? По сути JQuery - лишь библиотека для JS.