https://habrahabr.ru/company/jugru/blog/329302/- Программирование
- JavaScript
- Блог компании JUG.ru Group
Рано или поздно любой разработчик сталкивается с непонятными проблемами, а учитывая множество «особенностей» Vanilla JS, у нас это происходит довольно часто. Вне зависимости от причин поиск решений может затянуться или привести к созданию очередного велосипеда. А верный путь часто лежит на поверхности, нужно просто знать, где его искать и как применить полученные знания. О странностях и неожиданностях JS и их правильной интерпретации мы поговорим с экспертами в этой области Claudia Hernández и Jakob Mattsson.
Claudia Hernández
Claudia — Senior Frontend Engineer в парижском офисе Dailymotion. Пересекла Атлантику для работы над проектами для таких компаний, как Air France, EDF, Groupe SEB и Aéroport de Paris. Когда не пишет код, читает книги. Claudia также любит путешествовать и узнавать новые культуры.
— Claudia, добрый день! Расскажите, пожалуйста, немного о себе и о вашей работе.
Claudia Hernández: Здравствуйте! Меня зовут Claudia Hernández, я — мексиканский разработчик. Сейчас старший менеджер в Dailymotion в Париже. Скоро мы собираемся запустить самый важный проект, над которым компания трудилась несколько лет. Мы готовим полный редизайн платформы. Самое интересное заключается в том, что мы заменили наш старый стек и перешли к более интересным технологиям, таким как React. У меня была возможность узнать о GraphQL и Apollo. Нам предоставили свободу в плане подбора технологий, которые бы, по нашему мнению, наилучшим образом соответствовали проекту. Ежедневно я работаю с дизайнерами и бэкэнд-разработчиками, чтобы всем вместе довести новую платформу до конца.
— На HolyJS вы будете выступать с докладом "Down the Rabbit Hole: JavaScript in Wonderland". Вы не первый раз рассказываете об этом, скажите, как доклад изменяется со временем? Появляются ли новые необычные задачи и решения? Или количество «трюков» растет с развитием самого языка?
Claudia Hernández: Языку JavaScript скоро исполнится 22 года. В JS теперь возможны вещи, которые до недавних пор нам казалось нереальными. У нас есть фантастические инструменты, например Babel, который позволяет тестировать еще даже не одобренные функции.
Эволюция делает многие трюки устаревшими с течением времени. Например, трюк использования оператора ~ в сочетании с методом
Array#indexOf
method не является обязательным, поскольку появилась новая функция в ES7
Array#includes
.
Мы живем в быстро меняющемся мире, где все новые функции постоянно добавляются, тестируются и одобряются или отвергаются сообществом. Это определенно позволит решить многие проблемы, с которыми мы сталкивались в прошлом, но, я уверена, что это же вызовет новые проблемы, о которых мы еще и не задумывались.
Я искренне верю, что нам, разработчикам, очень важно понимать последствия всех этих изменений в JS. Очень легко начать работать в JS, но трудно понять язык в полном объеме. И, как это ни парадоксально, многие из этих ошибок имеют реальное логическое/историческое объяснение — и простое распознавание проблем на ранней стадии исключило бы последующую головную боль.
— Не все любят спойлеры, но очень хочется понять, чего ожидать. Планируется ли «погружение» в особенности языка и определенных конструкций, как например, call, join, filter или это будет рассказ про новые фичи, планируемые к выходу?Claudia Hernández: JavaScript — очень обширный, широкий язык. В нем есть много особенностей, о которых я могла бы поговорить, но я рассказываю именно о том, что доставило мне неприятности в прошлом. Теперь разговор фактически разделен на 4 части, по количеству тем, которые я буду обсуждать. Один раздел полностью посвящен объяснению внутренних элементов метода сортировки
Array#sort
. Я подробно расскажу о реальных алгоритмах, стоящих за ним в каждом движке JS. Сложно поверить, но иногда ваш собственный метод сортировки в JS может быть быстрее, чем родной! Бьюсь об заклад, немногие разработчики действительно думали о такой возможности, но это знание, может быть, пригодится, когда придется обрабатывать сложные случаи сортировки. Кроме того, я объясню тайну синтаксиса «JS Fuck», который многие люди, похоже, признают, но не имеют представления о том, как он на самом деле работает.
— Как вы думаете, часто ли у обычного разработчика, без десятилетнего опыта за плечами, встречаются вопросы, требующие нетривиальных решений и использования «трюков»?
Claudia Hernández: Я не думаю, что «встреча» с ошибкой зависит от опыта. Мы часто работаем над разными проектами с множеством различных требований, и то, когда один из этих «трюков» пригодится для конкретной задачи, лишь вопрос времени. Речь идет не только о самих трюках, но и о логике, лежащей в их основе.
Выразительность JS позволяет нам найти тысячи различных решений для проблемы и двигаться вперед. Понимание самого языка поможет нам в конечном счете стать лучше.
— Расскажите, пожалуйста, о красивых и необычных примерах манипуляций с кодом в JS?
Claudia Hernández: Хорошим примером являются побитовые операторы в JS. Они нечасто используются разработчиками… Почему? Их поведение состоит в том, чтобы взять в качестве параметра число, преобразовать его в последовательность битов, выполнить некоторую операцию над этими битами, а затем преобразовать результат в число. Очень необычно, если мы начнем использовать данные возможности в нашей повседневной работе.
Однако мы можем использовать truncate. Это быстрее, чем использование
Math.trunc():
const float = 281.0901
~~float // 281
float | 0 // 281
float << 0 // 281
float >> 0 // 281
float >>> 0 // 281
Недостатками является то, что вам нужно быть осторожным с очень большими числами, поскольку эти операторы выполняют 32-битные преобразования, и результаты могут быть ошибочными для значений более 2 миллиардов
— Существует ли определенный «пласт» разработки, где использование хитростей JS особенно актуально?
Claudia Hernández: На самом деле, нет. Понимание этих оговорок означает понимание языка. Понимание языка в глубокой форме является частью жизни разработчика. Для меня конечной целью этого доклада является демонстрация не причудливости JS, а того, что JS на самом деле представляет собой очень сложный язык, который заслуживает соответствующего изучения от начала и до конца.
— Скажите, пожалуйста, какое у вас сложилось мнение об использовании «магических типов» NaN, null и undefined? Или для вас они уже давно перестали быть загадкой?
Claudia Hernández: Проверка на то, чтобы наши переменные отличались от undefined или null, является частью нашей повседневной жизни. По крайней мере, я делаю это довольно часто. Нам нужны эти сравнения для обработки пустых состояний в наших приложениях. Они по-прежнему иногда меня удивляют. Null относится к object, даже если он является примитивным типом, undefined является самим типом, undefined и null являются свободно равными и так далее. Слишком много исключений. Мы должны быть осторожны, когда пользуемся ими.
— Существует ли у вас шпаргалка для корректного применения NaN, null и undefined в коде программы? Вы не могли бы привести пару примеров того, что точно делать не стоит.
Claudia Hernández: У меня нет шпаргалки. Когда я проверяю, существует массив или нет, я обычно проверяю, равен объект массива null или нет. Обычно это выглядит так:
!yourArray.length
Но, возможно, вы захотите также проверить, является ли переменная, на которую вы ссылаетесь, действительно массивом (а не каким-то другим типом объекта с таким свойством длины, как аргументы или NodeList), поэтому вы можете добавить к этому:
!Array.isArray(yourArray) || !yourArray.length
Если бы вы действительно хотели узнать, является ли значение JS в этом массиве пустым или null? Чтобы узнать, существует ли значение в заданной позиции, вы можете просто сделать:
position < yourArray.length
И, наконец, чтобы определить, было ли заданное значение в вашем массиве определено и содержит что-то отличное от null, вы можете просто дописать:
typeof yourArray[position] !== ‘undefined’ && youArray[position] !== null
Это можно упростить:
yourArray[position] != null
— Недавно в статье "Зачем использовать статические типы в JavaScript?" рассказывалось о библиотеке Flow. В следующей статье затрагиваются вопросы преимуществ и недостатков такой разработки. Как вы относитесь к возможности переключения между динамическими и статическими типами в JS? Можно ли считать это трюком, или это верное направление развитие языка?
Claudia Hernández: Я пришла из Java / C++. То, что JS динамически типизированный язык, было непривычно только в самом начале. Сейчас я думаю, что многие разработчики чувствуют себя вполне комфортно с этой парадигмой и действительно знают, как использовать ее в своих интересах.
Иногда динамический характер JS может быть полезен. Мне кажется, статическая типизация добавляет много ненужного многословия в код, он становится перегруженным. Однако я не говорю, что мы должны от них отказаться. Я понимаю их преимущества, например, уменьшение количества ошибок, ясность кода для большой команды, более простое обнаружение проблем. Я знаю, что есть случаи, когда добавление статического типа проверки предпочтительнее других.
Смысл в том, что если вы действительно хотите убедиться, что ваш код работает должным образом, вы должны больше полагаться на свой тестовый набор, чем просто на проверку типов. Хорошие тесты могут перехватить большинство ошибок, вызванных неправильными типами.
— Спасибо огромное за беседу. Будем рады ждать вас на конференции HolyJS 2017 Piter.
Claudia Hernández: Спасибо!
Jakob Mattsson
Jakob — технический директор, консультант, но в первую очередь разработчик. Работал в различных компаниях, в том числе в стартапах, финансовых организациях и в венчурных фондах. Занимался несколькими языками программирования, а также написал несколько своих собственных. Увлечен работой с JavaScript, объясняя это сочетанием простоты и применимости. Будучи поклонником библиотек, опубликовал 65 модулей JavaScript.
— Jakob, добрый день! Расскажите, пожалуйста, немного о себе и своей работе.
Jakob Mattsson: Добрый день! Я родился и вырос в Швеции, поэтому у меня есть что-то общее с вами. Я привык к холоду. Несколько дней лета в году, а затем 360 дней мороза.
Я начал программировать в старшей школе и с самого начала участвовал в стартапах. Я работал над всем: от рекламных систем и систем обратной связи до приложений для спортивной рыбалки и финансовых услуг. В настоящее время живу в Лондоне и работаю в печально известном хедж-фонде.
Мне нравится тратить свое время на создание и исследование систем, как в кодировании, так и вне его, например кубик-рубик или изучение рынка жилья.
— На HolyJS вы будете выступать с докладом "Forgotten funky functions". Вам не кажется, что все хотят слышать про новомодные штуки, например, трансдьюсеры или очередную реализацию Array#map и Array#filter, а вы поделитесь немного другой информацией. С чем это связано? Или все новое — это хорошо забытое старое?
Jakob Mattsson: Я думаю, что уже было много разговоров о новых библиотеках. Все всегда стараются говорить о современном. Для меня это не главное в JavaScript. Позвольте мне объяснить.
Я начинал программировать на JavaScript не потому, что он был популярным и модным. Я начал программировать JS, потому что он был простым и доступным. Я не был одним из тех разработчиков, которые создают сайты и поэтому должны были изучать JavaScript. Мне просто нужен был простой и переносимый скриптовый язык.
Я потратил пару недель, чтобы решить, какой именно использовать для проекта. Это было примерно в то время, когда вышла самая первая версия Node.js. Кандидатами были Bash, Perl, Ruby, Python и JavaScript. У каждого свое мнение о том, какой из них лучше, но для меня у JavaScript было два основных преимущества:
1) Он работал везде (в браузерах, на настольных компьютерах и др.).
2) У JS удивительно простой синтаксис. Стандартные циклы, if'ы и switch'и. Мне понравилось в JS то, что не было пространств имен, классов или тому подобного. Только правильные функции (с замыканиями) и лучший синтаксис объектов в мире (JSON).
Несмотря на то, что JavaScript был простым, вы могли создать из него все остальные сложные вещи и нетривиальные концепции. Пространства имен — это просто объекты. Классы — это просто функции. Частные переменные — это просто обычные переменные, захваченные в замыканиях. И так далее. Это было красиво.
Сегодня JavaScript меняется и развивается. Он теряет связь с простым ядром, многие новые разработчики могут даже не задумываться над этими проблемами и изменениями, а это очень важно. Поэтому я и решил поговорить о классических частях: забытое старое, как вы и сказали.
— Как вы думаете, async/await, достигший четвертой стадии в ECMAScript, можно считать чем то необычным, или это стандартно ожидаемый функционал?
Jakob Mattsson: У меня есть два мнения:
1) С одной стороны, это просто синтаксический сахар и не является чем то необычным.
2) С другой стороны, это хороший пример изменения языка. Я говорю о том, как JavaScript менялся за последние пару лет — и продолжает. JS был очень простым, и вы могли писать код без особых усилий. Теперь JavaScript пытается меняться. У него есть сила, т.к. он работает в различных средах, но постепенно он теряет свою легковесность. Мне кажется это немного грустным.
— Если вернуться к нашей теме, так ли часто вам в вашей работе приходится использовать «нестандартный» JS при написании кода, создавая хитрые конструкции, или всегда есть некрасивое, но стандартное решение?
Jakob Mattsson: Я думаю, что способность делать нестандартные вещи важна, и вы должны это делать, но только тогда, когда вам это действительно нужно. В основном я занимаюсь «магическими» вещами на низких уровнях. Нестандартного JS следует избегать в коде приложения высокого уровня, где живут объекты домена и бизнес-логика, но он может быть полезен при создании фреймворков и мощных функций.
Нет таких вещей, которые следует избегать «всегда». Есть время и место даже для самых сумасшедших вещей. В эссе «Beating the averages» Пола Грэма (основателя Y Combinator) этому есть очень хорошее объяснение. Я думаю, что он сформировал то, как я думаю о языках программирования.
— Вы не могли бы рассказать, о нестандартных примерах кода, которые, кроме как уловкой назвать нельзя.
Jakob Mattsson: Я не думаю, что такие вещи есть. Если абстрагироваться, это вполне нормальная ситуация. Думаю, единственное, в чем я был бы осторожен, это в том, что нужно задать себе вопрос «будет ли это работать одинаково во всех средах», потому что если ответ отрицательный, то это скорее всего плохая идея.
— В ваших или сторонних проектах сталкивались ли вы с необычным поведением программ? Встречались ли места, показавшиеся вам необычными, некорректно работающими даже при верном написании? Что делать разработчику в таком случае?
Jakob Mattsson: Когда что-то не работает или ведет себя странно, несмотря на то, что код написан «правильно», то проблема, как правило, не в компьютере, а в том, кто за ним сидит.
Возможно, разработчик неправильно интерпретирует техническое задание. Может быть, у него нет достаточного понимания инструментов — языка, структуры, библиотек, среды. Именно по этой причине важно понять основы и внутреннюю работу.
Классическим примером в JavaScript будет использование переменной цикла в for-loop, которая переходит к замыканию. Думаю, что каждый разработчик JS, который использовал его до его последних обновлений, столкнулся с этим. Нужно изучить инструменты и окружить себя умными людьми, которые могут объяснить и помочь в сложных ситуациях и тогда положительный результат не заставит себя ждать.
— Огромное спасибо за разговор. Будем с нетерпением ждать вас на конференции HolyJS в Санкт-Петербурге.
Jakob Mattsson: Спасибо. До встречи на конференции.
Полные темы докладов, которые наши спикеры представят на ближайшей Holy JS Piter, звучат так:
Claudia Hernández: Down the Rabbit Hole: JavaScript in Wonderland
Jakob Mattsson: Forgotten funky functions
Помимо Клаудии и Джейкоба, на конференции с интереснейшими докладами различной сложности по JS выступят и другие эксперты. Посмотреть, что ждет участников, можно, например, тут.
А доступ к 10 ключевым докладам с прошлого мероприятия мы открыли здесь.