«Странный» JS

В ДжаваСкрипте полно странностей, да, но популярная картинка, которая получила сейчас широкое хождение (не буду её приводить, просто суть перепишу) имеет отношение только к безграмотности её авторов. Суть такова:
[] + [] // массив + массив
"" // результат — пустая строка

[] + {} // массив + объект
"[object Object]" // В результате получаем объект? Ну ок

{} + [] // объект + массив
0 // 0? Реально?

{} + {} // объект + объект
NaN // Not a Number? WAT?
Выглядит очень всё ооочень странно, если думать, что происходит именно то, что написано в коментариях справа. На самом деле происходящее неверно интерпретировано авторами.

В ДжаваСкрипте фигурные скобки, помимо объекта, задают ещё и блок кода. В данном случае все «объекты» слева — на самом деле блоки кода. Откроем консоль и попробуем это доказать: Вот что происходит на самом деле (9.90КиБ) Как видите, в левый блок можно без труда добавить код и станет очевидно, что это не описание объекта. Так два последних обсуждаемых примера распадаются на две независимые команды — определение пустого блока кода, который ничего не выполнит и унарную операция «плюс» над пустым объектом или массивом.

С массивом, возвращающим пустоту при суммировании (конкатенации) всё ещё проще — в данном случае производится попытка вызвать метод toString, который у массива выводит строку его значений через запятую. Так как значений нет, строка пустая.

В общем, ничего сильно странного не происходит.
16 июня 2015 07:05

vladon (инкогнито)
16 июня 2015, 08:53

Ну то есть в целом странный синтаксис языка, конечно, без чётких и однозначных правил. Но ничего сильно странного не происходит.

bolknote.ru (bolknote.ru)
16 июня 2015, 08:55, ответ предназначен vladon

Синтаксис языка с чёткими и однозначными правилами, есть принятый стандарт, там всё это описано.

Иван (инкогнито)
16 июня 2015, 10:42

Не надо про стандарт. Это прокол языка, который делали за 10 дней. Я люблю JS, но не стоит писать в духе "так и было задумано".

bolknote.ru (bolknote.ru)
16 июня 2015, 10:49, ответ предназначен Ивану

Я нигде не написал, что «так было задумано». Я считаю, что язык надо знать и знаю, что такое поведение стандартизовано — стандарт есть, гадать не надо, надо просто понимать как оно работает. Я это поведение понимаю и никуда не заглядывая, знаю как сделать так, чтобы слева всё-таки было тоже объект.

Алексей (инкогнито)
16 июня 2015, 11:47

Да большинство этих WTF-ов от незнания авторами JS и переноса на JS своих знаний других языков или вообще своих фантазий. На wtfjs.com, например первым пунктом вообще идёт какой-то идиотизм. И из всех "wtf-ов" только «The Hungry Variable» не очевиден с самого начала.

bolknote.ru (bolknote.ru)
16 июня 2015, 13:25, ответ предназначен Алексею

The Hungry Variable
Это больше относится к особенностям «вебкитов»

Иван (инкогнито)
16 июня 2015, 13:59

Это очень неочевидное поведение. Оно вынуждает часто заглядывать в стандарт. У ПХП такая же история: вал дикостей, на каждую тебя тыкают в стандарт. Можно утверждать, что ты один умный, а остальные дураки, но сообщество все расставило по местам -- люди массово переходят на Питон\Руби. Хотят понятный код, а не тысячу пунктов в стандарте, чудаки! JS держится, поскольку еще нет альтернатив. Хотя уже пишут JS на Кофе- и Кложуре- скриптах.

bolknote.ru (bolknote.ru)
16 июня 2015, 14:02, ответ предназначен Ивану

Это очень неочевидное поведение. Оно вынуждает часто заглядывать в стандарт. У ПХП такая же история: вал дикостей, на каждую тебя тыкают в стандарт.
У ПХП нет стандарта, какой смысл их сравнивать?
Можно утверждать, что ты один умный, а остальные дураки, но сообщество все расставило по местам — люди массово переходят на Питон/Руби
Что-то я этого не наблюдаю. Наоборот, появился совершенно необузданный интерес к серверному ДжаваСкрипту. У Пайтона и Руби своя коробка дикостей и на Пайтоне я запросто напишу код, который с первого раза понять будет очень трудно (а Руби не знаю и знать не хочу)

Мимо проходил (инкогнито)
16 июня 2015, 22:42, ответ предназначен bolknote.ru:

Что-то я этого не наблюдаю.
Видимо, имелось в виду, что люди массово переходят на Python/Ruby с PHP, а не с JavaScript.
...на Пайтоне я запросто напишу код, который с первого раза понять будет очень трудно...
Просим, просим.

Артур Мудрик (инкогнито)
16 июня 2015, 23:43

Питон, Яваскрипт — так правильнее. И, да, знать всякие вот такие нестандартные штучки в ЯП, очень необычные и wtf'шные, совершенно не обязательно — только если повыделываться, а для реального программирования всё это знать не нужно.

o4kapuk (инкогнито)
17 июня 2015, 03:14

По-моему, чувак на самом деле грамотный, знающий все эти тонкости, но однажды захотевший сделать шоу.
А по теме — такие неочевидные моменты знать стоит, хотя бы чтобы избегать их использования в коде.

Иван (инкогнито)
17 июня 2015, 05:41

> на Пайтоне я запросто напишу код, который с первого раза понять будет очень трудно
Передергиваете. В питоне нельзя сложить список со словарем и получить None, к примеру. Будет либо ошибка, либо потребуется перегружать операторы. Это не превосходство именно питона -- это знак хорошего дизайна языка.

bolknote.ru (bolknote.ru)
17 июня 2015, 06:09, ответ предназначен Мимо проходилу

Просим, просим.
http://bolknote.ru/2008/09/07/~1842/

bolknote.ru (bolknote.ru)
17 июня 2015, 06:13, ответ предназначен Артуру Мудрику

Питон, Яваскрипт — так правильнее.
Питон — это змея, а Пайтон назван в честь «Монти Пайтона», устал писать каждый раз. А «Яваскрипт» — так я не говорю.
И, да, знать всякие вот такие нестандартные штучки в ЯП, очень необычные и wtf'шные, совершенно не обязательно — только если повыделываться, а для реального программирования всё это знать не нужно.
Знать такие вещи — обязательно. Не для того, чтобы их писать, а для того чтобы уверенно разбираться что происходит в коде. Иногда что-то из этой «экзотики» встречается в коде. И вовсе не потому что человек выпендривался, потому что он и не знал, что выпендривается — он код писал.

bolknote.ru (bolknote.ru)
17 июня 2015, 06:16, ответ предназначен Ивану

Передергиваете. В питоне нельзя сложить список со словарем и получить None, к примеру.
И тут нельзя, вы статью не читали что ли? Вот вам загадка из «Пайтона» (из второго, третий я не знаю): почему object больше пустого массива, но меньше пустого списка?
>>> () > object() > []
True

o.mokhov@ya.ru (инкогнито)
17 июня 2015, 07:06

А как же классика жанра? http://www.youtube.com/watch?v=FqhZZNUyVFM

angru (инкогнито)
17 июня 2015, 10:55

Python3
Traceback (most recent call last):
  File "print.py", line 3, in <module>
    print(() > object() > [])
TypeError: unorderable types: tuple() > object()
[Finished in 0.2s with exit code 1]

bolknote.ru (bolknote.ru)
17 июня 2015, 12:18, ответ предназначен angru

из *второго*, третий я не знаю

Алексей (инкогнито)
17 июня 2015, 12:52, ответ предназначен bolknote.ru:

При чём тут вебкит? Это просто факт, что range в регулярке работает по коду символа, а не по фантазиям автора.
Оно так и в перле работает

bolknote.ru (bolknote.ru)
17 июня 2015, 13:48, ответ предназначен Алексею

А… не разобрался я.

Иван (инкогнито)
17 июня 2015, 19:32

> почему object больше пустого массива, но меньше пустого списка?
Без понятия. Это прокол языка -- в тройке исправили. Я трачу свое время эффективней -- не сравниваю объекты разных типов и другим не даю в код-ревью.

bolknote.ru (bolknote.ru)
17 июня 2015, 20:35, ответ предназначен Ивану

Ну так и в JS никто не плюсует блок кода с объектом или массивом.

Кстати, я понятие имею. Объект меньше списка, потому что его первая буква «o» (object) идёт до «t» (tuple), а больше массива потому, что буква «l» (list) идёт ещё раньше. То есть сравниваются имена типов.

Все эти вещи нужно знать, не для того, чтобы писать так (я уже писал это выше, напишу ещё раз), а чтобы быстро разобраться в проблеме, когда она возникнет — когда что-то кто-то передаст не туда по ошибке.

Max (инкогнито)
18 июня 2015, 12:44

[] + {}
Почему получается "[object Object]" а не NaN ?

Max (инкогнито)
18 июня 2015, 12:53

Получается, что при +{} фигурные скобки воспринимаются как блок кода, а при " " + {} фигурные скобки воспринимаются как объект и вызывается метод toString() ?

bolknote.ru (bolknote.ru)
18 июня 2015, 13:27, ответ предназначен Max

[] + {}
Почему получается "[object Object]" а не NaN ?
Это не арифметическое сложение, а строковое (конкатенация). У обоих объектов дёргается toString(), потом преобразуется в строку. Можно в этом убедиться, если выполнить:
[] + {toString: function() { alert('1')} }

bolknote.ru (bolknote.ru)
18 июня 2015, 13:29, ответ предназначен Max

Получается, что при +{} фигурные скобки воспринимаются как блок кода
Нет. +{} — вызывается унарная операция (второго-то аргумента нет), {} воспринимается как объект. Унарная операция «+» не над числом даёт NaN.
а при " " + {} фигурные скобки воспринимаются как объект и вызывается метод toString() ?
Нет, тут просто не арифметическое сравнение, так как аргументы операции «+» не числа.

Max (инкогнито)
18 июня 2015, 14:19

Я так понимаю, получается, что если перед {} ничего нет - то это воспринимается как блок кода. Если же перед {} что-то написано, то это уже воспринимается как объект?
{} + {} - первый элемент - это просто блок кода.
({} + {}) - "[object Object][object Object]" т.е. первый элемент воспринимается уже как объект
Я правильно понял?

bolknote.ru (bolknote.ru)
18 июня 2015, 15:26

Я правильно понял?
Правильно. Можно ещё написать так: ({}) + {}. Это надо делать по той же причине, по которой оборачиваются вызов анонимной функции на месте её описания в скобки — чтобы обозначить, что тут выражение. Причём годится любой способ указания, что это выражение, просто скобки — более универсальный.
Если же перед {} что-то написано, то это уже воспринимается как объект?
Не что-то, а то, что указывает на выражение. Например, function a() {} + {}. Тут {} — блок кода, будет NaN, потому что JS разобъёт эту конструкцию на две — определение функции и +{}, а (function a() {}) + {} — тут уже будет выражение и пустой объект. Вернётся конкатенация строковых представлений.

bolknote.ru (bolknote.ru)
18 июня 2015, 16:30

Тут {} — блок кода
я имел ввиду, что {} после function блок кода, а после плюса — объект.

Roman (инкогнито)
20 июня 2015, 16:07, ответ предназначен bolknote.ru:

Знать такие вещи — обязательно. Не для того, чтобы их писать, а для того чтобы уверенно разбираться что происходит в коде.
Не обязательно. Практика показывает, что человек, который быстро делает работающее приложение на Angular/Ember/Node.js/Whatewer, пусть даже и с багами (которыми можно заняться потом), гораздо полезнее того, кто заморачивается всякими мелочами. Идеальное знание языка в принципе может понадобиться, когда делаешь библиотеку, предназначенную для разработчиков, и то не всегда.

bolknote.ru (bolknote.ru)
21 июня 2015, 11:22, ответ предназначен Roman

Моя практика говорит о том, что человек в критической ситуации сходу понимающий где проблема гораздо более редкий и ценный, чем те, которые умеют быстро наколхозить. А такие люди (которые быстро понимают где проблема) невозможны без опыта знания тонкостей.

Возможно мы просто разными продуктами занимаемся. У нас продукт большой длительности (годы и десятилетия).

Артур Мудрик (инкогнито)
25 июня 2015, 13:05, ответ предназначен bolknote.ru:

человек в критической ситуации сходу понимающий где проблема
А такие люди (которые быстро понимают где проблема) невозможны без опыта знания тонкостей.
Это претенциозные надуманные глупости. Когда, например, вы получаете один результат функции (например, массив) и второй результат функции (например, объект) и видите, что дальше происходит сложение этих результатов, то тут не нужно знать тонкости языка, не нужно быть каким-то сверхопытным сверхначитанным программистом, чтобы прийти к выводу, что происходит бред или магия или слишком тонкие выпендрежные материи и так нельзя и это нужно исправить или переделать или упростить и тогда всё будет хорошо. Еще раз подчеркиваю — совершенно и гиперабсолютно не нужно знать тонкости языка (в частности вот все эти задачки из поста и их вариации).

Вообще, когда вот читаю такие статьи в вашем блоге (про магию языка и что это на самом деле не магия, а нужно просто знать свой язык идеально иначе ты не прогарммист... ну и пошло-поехало), то всегда такое чувство что вы выпендриваетесь и преувеличиваете собсвтенную важность. Выпендрежность заключается в том, что вы пытаетесь блеснуть знаниями и искренне выразить свое фи и удивляться, мол, "как!? это жы элементарщина, это жы азы языка, это жы должен знать любой программист, иначе он не программист, фу, ужас!!1". Такое чувство, что вы специально читаете документацию и лезете в дебри языка, чтобы потом написать в блоге, что это элементарщина, что это вообще прямо очевидно даже слепому не-программисту и позор тем программистам, кто не знает всякие такие необычные штучки в языке. Вы начитались где-то вот о таких необычных тонкостях языка и теперь выпендриваетесь и пытаетесь искусственно искренне удивляться, когда кто-то не знает о том, что знаете (теперь) вы. Программистское ханжество, вот, придумал, это так называется.

bolknote.ru (bolknote.ru)
25 июня 2015, 21:24, ответ предназначен Артуру Мудрику

Это претенциозные надуманные глупости.
Это мой опыт.

Roman (инкогнито)
4 июля 2015, 21:13, ответ предназначен bolknote.ru:

Я вообще-то тоже только долгосрочными продуктами занимаюсь. Про вас я в курсе. Ужасный у вас продукт.

bolknote.ru (bolknote.ru)
5 июля 2015, 11:59, ответ предназначен Roman

Про меня вы не в курсе совершенно.

bolknote.ru (bolknote.ru)
5 июля 2015, 20:03, ответ предназначен Roman

Ужасный у вас продукт.
Какой из?

Roman (инкогнито)
7 июля 2015, 02:46, ответ предназначен Roman

Абсолютно все. Конечно, я имею в виду компанию, в которой вы работаете. Хотя в вашем Гитхабе я тоже ничего полезного не обнаружил.

bolknote.ru (bolknote.ru)
7 июля 2015, 06:56, ответ предназначен Roman

Абсолютно все. Конечно, я имею в виду компанию, в которой вы работаете.
Ни один работающий в нашей компании сотрудник, не знает подробностей о качестве всех продуктов. Вам-то откуда знать?
Хотя в вашем Гитхабе я тоже ничего полезного не обнаружил.
Возможно это как-то связано с тем, что программирование — это моё хобби, а не профессиональная деятельность. Видите, вы действительно ничего обо мне не знаете.

Roman (инкогнито)
10 июля 2015, 20:22, ответ предназначен bolknote.ru:

Я примерно представляю, каким может быть российский продукт, разрабатываемый десятилетиями на ПиЭйчПи, да еще и за гос. бабло. Интересно, много людей туда наколхозило? Хотя, я могу ошибаться, может у вас там "ЕкмаСкрипт Сикс" давно, тогда могу только порадоваться.

bolknote.ru (bolknote.ru)
10 июля 2015, 20:47, ответ предназначен Roman

Теперь всё встало на свои места.

pavelpat (инкогнито)
1 августа 2015, 19:47

Элементарно ж.
Если питон не может сравнить 2 объекта (у них не обределены методы для сравнения) то он превращает их (одного из них) в строки (берет имя типа) и сравнивает строки через strcmp (object.c:794).

pavelpat (инкогнито)
1 августа 2015, 19:48

https://docs.python.org/3/whatsnew/3.0.html#ordering-comparisons

Ваше имя или адрес блога (можно OpenID):

Текст вашего комментария, не HTML:

Кому бы вы хотели ответить (или кликните на его аватару)