JavaScript

Приколы JS со сравнением []==[]

Объясните, почему в js []==[]//false ; []==![]//true ; {}=={}// false ; {}==!{}// false...
Как происходит это сравнивание, есть ли для таких сравнений специальное название, где можно почитать об этом поподробнее?
Забавно читать ответы людей которые якобы "разбираются", но почему-то не могут объяснить.

[] это литерал объектного типа Array. Естественно, два литерала не равны, это ведь разные экземпляры... все равно что взять два яблока и спросить: "они являются одним и тем же яблоком?". Очевидно, нет. По тому же принципу что и с пустыми литералами, результат [1] == [1] будет false. А вот (let a = [], b = a; a == b) === true, потому что обе переменные ссылаются на один и тот же экземпляр.
{} - абсолютно то же самое, только тип Object.
Выражение !{} - явный типкаст литерала объекта к значению типа Boolean, и его инверсия (вернет false, т. к. Boolean({}) === true).

Специального названия нет, сравнение оно и в Африке сравнение.
Почитать можно в спецификации ECMAScript.
Сергей Пряхин
Сергей Пряхин
93 754
Лучший ответ
Сергей Пряхин *явный типкаст литерала объекта к значению типа Boolean, ЧЕРЕЗ инверсию (логическое "не")
так точнее.
Adyrbekov Kuanysh Да, единственный нормальный ответ.
Но почему []==![] ?
однако {} == !{} возвращает false
Adyrbekov Kuanysh Ещё интересней
[0] == ![0] // true
[8] == ![8] // false
Возможно, тут каким-то образом используется преобразование массива в число.
Я тебе ещё с полсотни таких приколов могу написать, это называется преобразование типов на этой основе можно писать шифрованный код Javascript вот как то на досуге написал alert(!+[]!=!![]?[]+!!![]:!+[]+!![]>!!"["?((!!!![]+!''+!!"["+!+[]+!'')**(!![]+!+[]+!!!""%!''+!!{}+!''+!!'<'+!+"?")):!!'#@$%^&!^%'); можешь понять какое число я загадал не запуская код ?
Дальше гуще !

Ну а теперь пишем небольшую шифрованную программку alert(15);

''[(''+{})[!''<<!''<<!''|!'']+(''+{})[-~'']+(''['']+'')[+!'']+(![]+'')[!''<<!''^!'']+(!''+'')[+'']+(!''+'')[+!'']+(''['']+'')[+'']+(''+{})[!''<<!''<<!''|!'']+(!''+'')[+'']+(''+{})[-~'']+(!''+'')[+!'']][(''+{})[!''<<!''<<!''|!'']+(''+{})[-~'']+(''['']+'')[+!'']+(![]+'')[!''<<!''^!'']+(!''+'')[+'']+(!''+'')[+!'']+(''['']+'')[+'']+(''+{})[!''<<!''<<!''|!'']+(!''+'')[+'']+(''+{})[-~'']+(!''+'')[+!'']]((![]+'')[+!'']+(![]+'')[!''<<!'']+(!''+'')[!''<<!''^!'']+(!''+'')[+!'']+(!''+'')[+'']+'('+-~''+(-~!''<<!''^!'')+')')();

Как видишь я не использовал не одного текстового символа но если ты скопируешь эту кракозябру в окно терминала и запустишь то она будет работать :) :) :) вот что значить знание языка Java Script

Юрий
Юрий
63 238
Иван Кузнецов Страшная хуйня, но интересная, спасибо
Алексей Антонов Одним словом гений
Я как человек использующий все современные плюшки языка и хорошо понимающий основы скажу следующее: принять и простить. В JS много магии и когда к ней привыкаешь - такое поведение сравнений оказывается понятным и логичным, а вот при переходе с других языков ну нихрена не логично, знали бы Вы какой там пипец творится с округлением чисел после запятой или как получить индекс месяца 71, вместо 8 ну и всё в таком духе, не сдавайтесь, дальше будет проще и лучше всё-таки компилировать посредством бабеля, многие идиотские костыли реализованы куда более элегантным способом.
Алексей Маслак
Алексей Маслак
73 780
Иван Кузнецов Я рад за такую простыню пожеланий и воодушевлений, но мне больше интересно, как работает именно то, о чем я написал в вопросе. Про магию и прочее в js я уже давно понял.
Юрий мой первый набросок от руки мыглядел так

''[(''+{})[!''<<!''<<!''|!'']+(''+{})[-~'']+(''['']+'')[+!'']+(![]+'')[!''<<!''^!'']+(!''+'')[+'']+(!''+'')[+!'']+(''['']+'')[+'']+(''+{})[!''<<!''<<!''|!'']+(!''+'')[+'']+(''+{})[-~'']+(!''+'')[+!'']][(''+{})[!''<<!''<<!''|!'']+(''+{})[-~'']+(''['']+'')[+!'']+(![]+'')[!''<<!''^!'']+(!''+'')[+'']+(!''+'')[+!'']+(''['']+'')[+'']+(''+{})[!''<<!''<<!''|!'']+(!''+'')[+'']+(''+{})[-~'']+(!''+'')[+!'']]((![]+'')[+!'']+(![]+'')[!''<<!'']+(!''+'')[!''<<!''^!'']+(!''+'')[+!'']+(!''+'')[+'']+'('+-~''+(-~!''<<!''^!'')+')')();

что соответствует коду javascript alert(15);

Adyrbekov Kuanysh В программировании нет никакой магии. Магия появляется в голове от недостатка знаний.
Тебе нужно почитать про преобразование типов, когда ты пишешь !{} - происходит преобразование в boolean т. к. объект пустой, он преобразуется в False, дальше уже происходит сравнение {} == False - естественно вернется False т. к. False != {}
Дмитрий Шведов
Дмитрий Шведов
73 814
Сален Нурушев зато [] == false =)
Юрий А некоторые типы пишут таким способом программы вот мой первый набросок от руки выглядел так

''[(''+{})[!''<<!''<<!''|!'']+(''+{})[-~'']+(''['']+'')[+!'']+(![]+'')[!''<<!''^!'']+(!''+'')[+'']+(!''+'')[+!'']+(''['']+'')[+'']+(''+{})[!''<<!''<<!''|!'']+(!''+'')[+'']+(''+{})[-~'']+(!''+'')[+!'']][(''+{})[!''<<!''<<!''|!'']+(''+{})[-~'']+(''['']+'')[+!'']+(![]+'')[!''<<!''^!'']+(!''+'')[+'']+(!''+'')[+!'']+(''['']+'')[+'']+(''+{})[!''<<!''<<!''|!'']+(!''+'')[+'']+(''+{})[-~'']+(!''+'')[+!'']]((![]+'')[+!'']+(![]+'')[!''<<!'']+(!''+'')[!''<<!''^!'']+(!''+'')[+!'']+(!''+'')[+'']+'('+-~''+(-~!''<<!''^!'')+')')();

что означает alert(15);

Да некомпактно зато звучит как операция Ы типа чтоб некто не догадался :)

Приколы обфускации (умное слово, означающее "запутывание" в ПО) - фактически форма криптографии.

JSFuck — это эзотерический и образовательный стиль программирования, основанный на атомарных частях JavaScript. Он использует только шесть разных символов для написания и выполнения кода.

Он не зависит от браузера, поэтому его можно запустить даже на Node.js.

Используйте форму ниже, чтобы преобразовать свой собственный скрипт. Снимите флажок «eval source», чтобы получить обычную строку.

http://www.jsfuck.com/

Basics
false => ![]
true => !![]
undefined => [][[]]
NaN => +[![]]
0 => +[]
1 => +!+[]
2 => !+[]+!+[]
10 => [+!+[]]+[+[]]
Array => []
Number => +[]
String => []+[]
Boolean => ![]
Function => []["filter"]
eval => []["filter"]["constructor"]( CODE )()
window => []["filter"]["constructor"]("return this")()
С!
Сэр !!!
67 723