Как будет отсортирован следующий массив [-1, 0, 1, 2, -1, -4, -2, -3, 3, 0, 4].sort()?
? Предыстория
На выходных я решал литкод, и в задаче 3sum было необходимо отсортировать массив по возрастанию, перед тем как перейти к основной реализации алгоритма.
Я написал решение, подебажил на бумаге — всё работает, отправляю код на проверку — не работает ?♂️. Перепроверяю всё глазами — ну должно же работать!
Сдаюсь и начинаю дебажить в VS Code и вижу, что сортировка массива работает не так как я ожидал.
ℹ️ Объяснение
Если перейти на MDN и прочитать документацию Array.prototype.sort(), то станет всё понятно.
Метод sort() в JavaScript преобразует элементы в строки и затем сравнивает их последовательности значений кодов UTF-16. Это означает, что при сортировке числа рассматриваются как строки.
Таким образом, числа в данном случае сортируются на основе их строкового представления. Например, '-10' будет идти перед '-2', потому что строка '10' идет перед строкой '2' в лексикографическом порядке.
Чтобы выполнить числовую сортировку массива, нужно предоставить функцию сравнения методу sort(), как показано здесь:
[-1, 0, 1, 2, -1, -4, -2, -3, 3, 0, 4].sort((a, b) => a - b);
Я уже упоминал атомарные обновления, когда говорил о проблемах контекста реакта.
Я называю обновления атомарными, если компонент обновляется только тогда, когда изменяются данные, которые он использует. У контекста реакта с этим большие проблемы, но и при использовании Zustand можно выстрелить себе в ногу.
Zustand сравнивает по ссылке предыдущее и текущее значение, возвращаемое из useStore(), и если объект изменился — происходит ре-рендер.
❌ В следующем примере у нас всегда будет возвращаться новый объект, и ре-рендер произойдёт даже если изменился только age, а lastName и firstName не изменились
Каррирование и частичное применение — две концепции из функционального программирования, которые очень часто путают из-за их схожести (а я пишу этот пост, чтобы наконец-то запомнить).
И частичное применение, и каррирование, реализуются как функции, принимающие в качестве параметра другую функцию.
Частичное применение — функция partialApply, принимающая первым параметром функцию — fn, а остальные параметры — часть параметров функции fn. Функция partialApply возвращает функцию, которая в качестве параметров принимает недостающие аргументы функции fn.
Каррирование — функция curry, которая принимает единственный параметр — функцию fn, и возвращает каррированную функцию fn. Можно сказать, что каррированная функция fn — функция аккумулятор, которая будет накапливать переданные аргументы до тех пор, пока не будет передано достаточно параметров для вызова исходной функции. Параметры можно передавать в любом количестве.
Когда вы передаете в then() что-то отличное от функции (например, промис), это интерпретируется как then(null) и в следующий по цепочке промис «проваливается» результат предыдущего.
Amazon опубликовала компилятор jsii 1.90, представляющий собой модификацию компилятора TypeScript, позволяющую извлечь из компилируемых модулей информацию об API и сгенерировать универсальное представление данного API для обращения к JavaScript-классам из приложений на различных языках программирования. Код проекта написан на TypeScript и распространяется под лицензией Apache 2.0.
Jsii даёт возможность создавать на языке TypeScript библиотеки классов, которые могут использоваться в проектах на языках C#, Go, Java и Python, благодаря трансляции в родные для этих языков модули, предоставляющие тот же самый API. Инструментарий используется в AWS Cloud Development Kit для поставки библиотек для разных языков программирования, формируемых из одной кодовой базы. В новой версииjsii реализовано кэширование списка классов для каждой сборки и документировано, как можно превратить обязательное свойство в необязательное.
В статье автор предлагает отказаться от экспортов по-умолчанию в JavaScript. Я бы выделил 2 причины, которые кажутся для меня наиболее важными:
1️⃣ Дефолтные экспорты не указывают имя функции или класса, которую вы импортируете, что может (и будет) вызывать неконсистентность в именовании.
2️⃣ Когнитивная нагрузка замедляет разработку. Если вы используете дефолтные экспорты, вам придётся самостоятельно, каждый раз указывать название импорта. В случае с именованными экспортами ваша IDE наверняка подскажет вам имя, как только вы начнёте печатать и вам останется лишь нажать Enter.
Если вы всегда используете именованные экспорты, вам больше не нужно выбирать между именованными и дефолтными экспортами. Например, если изначально в файле вы экспортировали только одну функцию и теперь вам нужно экспортировать ещё одну, вам не придётся заменить везде неименованные импорты на именованные.
? ESlint
Чтобы убедиться, что все разработчики используют именованные экспорты, вы можете использовать правило import/no-default-export
Когда я добавлял это правило в наш проект, я наткнулся на GitLab issue, где команда Гитлаба планировали перейти с дефолтных экспортов на именованные. Они также ссылаются на эту статью.
В конце прошлого года в Google Chrome появились 2 новых режима
Memory Saver (Экономия памяти)
Energy Saver (Энергосбережение)
Они позволяют более гибко управлять использованием системных ресурсов браузером.
Memory Saver: Этот режим автоматически освобождает неиспользуемые фоновые вкладки, чтобы освободить память для активных вкладок и других запущенных приложений. Но для сложных сайтов с интерактивностью это может привести к проблемам восстановления состояния страницы.
Energy Saver: Режим Energy Saver позволяет браузеру снизить частоту обновления экрана для экономии заряда батареи. Обычно, для большинства сайтов, не требуется внесение изменений, но если вы используете JavaScript-анимации, имейте в виду, что они могут замедлиться.
? Важно, чтобы веб-разработчики учитывали эти новые режимы и обеспечивали безупречный опыт для пользователей. Рекомендуется сохранять состояние пользователей при изменении их активности и обрабатывать перезагрузки страницы после удаления вкладок.
Парни в докладе рассказывают, как можно не заниматься формошлёпством, точнее как его упростить, чтобы создавать новые формы можно было проще и быстрее.
Backend Driven UI представляет собой подход, в котором бэкенд говорит клиенту, как должен выглядеть интерфейс. В случае с формами, например, может передаваться массив элементов, где у каждого элемента есть тип:
- header
- select
- checkbox
- …
клиент проходится по этому массиву и рендерит соответствующий UI компонент. Таким образом реализация компонентов находится на фронте, а их расположение и взаимодействие на бэке.
? Основные преимущества Server Driven UI
- Возможность делегировать создание форм бэкендерам или аналитикам
- Мгновенные релизы, достаточно обновить данные на сервере для изменения формы сразу на всех устройствах
Если вам приходится собеседовать начинающих фронтендеров, то следующая простая задача поможет вам проверить, понимает ли разработчик принцип работы с замыканиями, и может ли он применять их на деле.
/**
* Нужно написать функцию, которая принимает число N и возвращает функцию,
* вызов которой первые N раз возвращает 'yes', а потом – 'no'.
*/
function canGetCount(n) {
// code here
}
const getOne = canGetCount(2);
getOne() === 'yes'
getOne() === 'yes'
getOne() === 'no'
У меня есть экспертиза и уникальный материал по следующим темам:
Реактивное Программирование (FRP, ORP и тд)
Бесконфликтные Алгоритмы (OT, CRDT и тд)
Ни на западе, ни у нас аналогов нет. Тем более с таким глубоким погружением. Думаю вот, может сделать курсы по этим темам для продвинутых. Но не знаю на сколько это востребовано. Кому интересно - отпишитесь, пожалуйста, в этой форме.
Тут я расписал подробнее, как я их вижу. По первому большая часть материалов уже есть. По второму пока только зачатки.
Если вы используете бесплатную IntelliJ IDEA Community Edition, то из поддержки JS и CSS там только весьма скудная syntax highlighting only подсветка синтаксиса, но есть простой способ её улучшить.
В этом нам поможет плагин TextMate Bundles, который уже встроен в современных версиях IDEA. В этом плагине уже встроены бандлы для JavaScript и CSS, причём, с достаточно неплохой подсветкой синтаксиса. Загвоздка в том, что эта подсветка не работает из коробки, т.к. её перекрывает та самая syntax highlighting only подсветка.
Чтобы всё заработало, идём в Settings > Editor > File Types и удаляем File name patterns для CSS (syntax highlighting only) и JavaScript (syntax highlighting only). Тоже самое можно проделать и для SQL (syntax highlighting only).
Пример было/стало для JavaScript:
Сравнение подсветки JavaScript.
К сожалению, это не даёт подсветку синтаксиса для CSS и JavaScript встроенных в соответствующие HTML тэги.