Во многом "смотрим и повторяем" - это классический подход к изучению языков, в том числе и языков программирования. Однако для изучения синтаксиса ЯП это работает первые несколько минут/часов/дней.
Далее необходимо менять подход, и важно погрузиться в концепции стоящие за ЯП.
Если скажем попытаться сложить "1" + 1 в Python, то случится TypeError, а JavaScript скажет: "спасибо дальше, я сам!".
Все дело в типизации.
Язык JavaScript обладает динамической и слабой типизацией. Давайте разберемся как это влияет на пользование этим ЯП и на сам ЯП
Часть того, от чего плюются разработчики, и что они называют "магией" исходит от слабой типизации. Трактовки слабой типизации в сети могут встречаться разные, однако все они связаны с приведением типов.
Если в выражении ЯП позволяет совершать операции м/у значениями одного типа будем считать такой ЯП абсолютно строгим, если между значениями всегда и везде любых типов то абсолютно слабым.
Однако в своей скромной практике я не встречал таких "абсолютных" языков, ведь даже в JS есть ошибки приведения типов, в языка "посильнее" могут происходить неявное преобразование типов, например при работе над числами docs.microsoft.com/ru-ru/dotnet/c…
Спецификация описывает помимо всего прочего, то как должен себя вести язык. Она описывает набор абстрактных операторов, которые отвечают за неявных преобразования. И то как должно происходить приведение к конкретному типу
Рассмотрим один из таких операторов ToNumber, как видно в JS присутствуют недопустимые преобразования, возникает TypeError
Когда "JavaScript-движок" получает выражение, он преобразует его в AST, откуда становится очевидным какие операторы будут исполнены и с каким значениями.
Например небольшое выражение:
[1] + [] + 42
Выполнится сначала оператор (+) с аргументами [1] и [], оператор (+) далее результат прошлого вычисления и 42
И если обратится снова к спецификации, то можно обнаружить описание работы оператора (+), в котором присутствует уже упомянутый абстрактный оператор приведения типов ToNumber.
И по итогу вся магия вычислений сводится к тому, как JavaScript бегает по этим таблицам приведений
На досуге пытался выяснить можно ли встроенными средствами JavaScript сделать его сильнее, мб отменить некоторые операции, переписать что-то, чтобы отдавалось TypeError, и понять насколько же JavaScript сильный
Благодаря неявным преобразованиям и некоторым конструкциям языка, можно написать вполне валидный и запускаемый код с помощью всего лишь 6 символов, jsfuck.com или 8 символов patriciopalladino.com/files/hierogly…
В jsfuck происходит добыча каждого символа практически из самых недр неявных преобразований
Касательного того, почему и как это работает можно почитать в статье sking7.github.io/articles/14388… или в ролике собственного производства (длительность 6 минут)
В общих чертах, о том как работает анализатор пакетов от npms.io написано у них на сайте: npms.io/about
Если нужно больше деталей, то можно изучить репозиторий (github.com/npms-io/npms-a…) или уговорить меня собрать в тред результаты моего исследования =)
1) Проект bundlephobia.com я очень люблю и пользуюсь им почти каждый день. Здесь можно получить такую информацию как: вес импорта JS-кода (min и gzip), число прямых зависимостей и поддержка tree-shaking.
Также очень полезно посмотреть распределение веса. Зачастую авторы библиотек выбирают зависимости так неудачно, что для маленьких опциональных фич используются зависимости, которые весят в несколько раз больше кода самого пакета.
Если вы видите, что популярный пакет сложно сделать легче или автор не хочет принимать PR-ы на эту тему, вы можете просто попробовать найти альтернативу.
Моя мысль в том, что если мы все изменим подход к подбору зависимостей, то лучшие библиотеки станут популярнее.
Учитывая, например, алгоритм сортировки поиска NPM: чем больше пакет скачивают, тем выше он в выдаче. Поэтому самое простое, и при этом не такое бесполезное, что вы можете сделать — не устанавливать плохие пакеты.
Но как заранее понять что пакет плохой/хороший, спросите вы?
Давайте сперва посмотрим на типичный флоу по поиску и установке пакетов:
Google/NPM → GitHub → npm install looks-good
Проблема в том, что на этих шагах мы почти не встречаем метрик, которые характеризовали бы качество пакета.
Как можно сделать существующую библиотеку легче? Вариантов много, но начал бы со следующих пунктов:
1. Удалить зависимости или заменить их на более легкие.
Пример: заменить moment на date-fns (или на стандартный Date) или styled-components на какой-нибудь goober.
2. Настроить tree-shaking, чтобы неиспользуемый код зависимости не попадал в бандлы сайтов. Особенно актуально если библиотека предоставляет множество различных экспортов (как lodash).
По сути, нужно просто настроить поле sideEffects в package.json.
Итак, пакеты которые разработаны без заботы о размере и доступности зачастую становятся очень популярны и делают веб хуже. Что же мы, как комьюнити, можем сделать?
Разумеется, раз это open-source, то можем делать Pull Request-ы, чтобы улучшить эти популярные либы.
Звучит разумно и благородно, но получается не всегда.
Например, однажды я решил помочь одной библиотеке: сделал PR, где настроил инструменты для отслеживания размера и сказал автору, что помогу ему сделать либу легче. Однако мейнтейнер сказал, что ему это не интересно.
К тому же, зачастую, если пакет изначально разрабатывался без мыслей о размере, то его либо сложно, либо невозможно сделать легче хотя бы на 10%
Тот же tinycolor2 спроектирован как moment: сделать его ощутимо легче без потери функционала и без кучи breaking changes уже не выйдет
Почему я вообще считаю, что надо заморачиваться на тему числа и веса зависимостей? Кто-то скажет: «10 КБ или 100 КБ — какая разница? Все равно это мало! Не мегабайт же!»
Проблема в том, что в проектах редко бывает только одна зависимость, а если у вас 10 зависимостей по 100 КБ, то это уже мегабайт, а если 10 зависимостей по 10 КБ — это в сумме всего 100 КБ.
Представим, что вам надо по-быстрому сделать форму на нескольких языках с колор-пикером, автосаджестом и еще парой каких-нибудь кастомных полей...