truefrontender | Unsorted

Telegram-канал truefrontender - True Frontender

1070

Сборная солянка про фронтенд. JavaScript, React, TypeScript, HTML, CSS — здесь обсуждаем всё, что связано с веб-разработкой! Связь: @pmowq

Subscribe to a channel

True Frontender

Привет! Сегодня я хочу поговорить о принципе DRY (Don't Repeat Yourself) и поделиться своими мыслями о том, как его правильно применять.

Применение DRY не всегда означает стремление к избавлению от любого дублирования кода. На самом деле, ключ к успешному использованию DRY заключается в понимании, когда и как нужно обобщать код.

Вот простой и эффективный подход к применению DRY:
1. Когда вы сталкиваетесь с новой задачей, начните с решения, нацеленного на конкретный случай. Это позволяет быстрее разработать работающий код и лучше понять задачу.
2. Если похожая задача возникает во второй раз, используйте уже написанный код, адаптируя его под новые условия. Важно здесь отметить в коде, что произошло повторение, чтобы быть осведомленным о потенциальной необходимости в дальнейшем обобщении.
3. Когда вы сталкиваетесь с проблемой в третий раз, это является сигналом к обобщению. Теперь у вас есть достаточно контекста и понимания для создания универсального решения.

Этот подход помогает избежать преждевременной абстракции и усложнения кода. Он также позволяет более глубоко понять проблему, прежде чем переходить к обобщенному решению.

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

А что вы думаете на счет DRY?

Читать полностью…

True Frontender

Привет 👋! Начнем эту неделю с задачи, которую я встретил на одном из собеседований. Эта задача может и не является популярной, но она достаточно интересна и имеет разные варианты.

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

Пример
В банкомате имеются: 2 купюры по 5000 рублей, 3 купюры по 1000 рублей, 5 купюр по 500 рублей и 10 купюр по 100 рублей. Пользователь хочет снять 8800 рублей. Каков будет ваш подход к выдаче этой суммы, используя купюры наибольшего номинала, которые доступны в банкомате?

Алгоритм решения:
1. Итерируемся по массиву denominations.
2. Для каждого номинала определяем, сколько купюр мы можем использовать, чтобы приблизиться к запрашиваемой сумме, не превышая ее.
3. Вычитаем из запрашиваемой суммы соответствующее количество денег и добавляем данные о выданных купюрах в результат.
4. Продолжаем, пока не выдадим всю запрашиваемую сумму или пока не пройдем все доступные номиналы.

Решение:

const denominations = [
[5000, 2],
[1000, 3],
[500, 5],
[100, 10]
];

function withdraw(amount) {
let result = [];

for (let [denom, count] of denominations) {
let usableCount = Math.min(count, Math.floor(amount / denom));
if (usableCount > 0) {
amount -= usableCount * denom;
result.push([denom, usableCount]);
}
if (amount === 0) break;
}

return amount === 0 ? result : null; // Возвращаем null, если не можем выдать всю сумму
}

console.log(withdraw(8800));


А теперь интересно узнать ваше мнение! Как вам эта задача? Какие альтернативные способы решения этой задачи вы можете предложить?

#javascript #interview

Читать полностью…

True Frontender

Привет! Наконец-то наступила пятница 🍺 Я, как и многие, всегда жду выходные, потому что можно чуть дольше посидеть за компом и не волноваться о том, что просплю дейли. Сейчас, буквально за пару секунд, я поделился с вами частью своих планов на выходные. Так же быстро и легко можно делиться информацией с помощью Web Share API, о котором пойдет речь сегодня.

Что такое Web Share API?
Web Share API - это интерфейс программирования приложений, который позволяет приложениям использовать нативный механизм обмена данных операционной системы. Проще говоря, это позволяет пользователям делиться контентом, таким как текст, ссылки или файлы, напрямую через встроенные в их устройство функции обмена.

Как это работает?
Вызов navigator.share() открывает нативное диалоговое окно обмена устройства. Этот метод принимает объект, который может содержать 4 свойства:
1. title - заголовок
2. text - текст
3. url - ссылка
4. files - массив файлов

Пример использования:

const shareData = {
title: '@TrueFrontender',
text: 'Подпишись!',
url: '/channel/TrueFrontender'
};

shareButton.addEventListener('click', () => {
if (!navigator.canShare) {
console.log('Браузер не поддерживает Web Share API')
}

if (navigator.canShare && navigator.canShare(shareData)) {
navigator.share(shareData)
.then(() => console.log('Поделились!'))
.catch((error) => console.log('Ошибка:', error));
} else {
console.log('Браузер не поддерживает Web Share API для данного типа данных.');
}
});

canShare - этот метод позволяет проверить, поддерживает ли браузер обмен определенными типами данных, что предотвращает возможные ошибки.

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

Заключение
Web Share API - это мощный и простой инструмент, который может оказать значительное влияние на взаимодействие пользователей с вашим сайтом.

Читать полностью…

True Frontender

Привет, дорогие читатели 🤗! Уже наступила среда, а это значит, что половина недели успешно пройдена, и мы стали еще ближе к выходным 🪱
Сегодня хочу вместе с вами базово разобрать методологию BEM (Block, Element, Modifier) и её роль в организации CSS.

Что такое BEM?
BEM разделяет интерфейс на независимые блоки, что упрощает поддержку кода. Он состоит из трёх компонентов:
1. Блок - это независимый компонент интерфейса, например, кнопка или меню.
2. Элемент - это часть блока, выполняющая определённую функцию. Например, пункт в меню.
3. Модификатор - это свойство блока или элемента, определяющее его внешний вид или поведение, например, активный пункт меню.

Пример:

/* Блок */
.menu { ... }

/* Элемент */
.menu__item { ... }

/* Модификатор */
.menu__item_active { ... }


Преимущества использования BEM:
- Стили становятся более предсказуемыми. Вы сразу видите, какие стили относятся к конкретному блоку или элементу.
- Облегчается переиспользование компонентов. Блоки могут быть использованы в разных частях проекта без конфликтов стилей.
- Масштабируемость проекта улучшается. BEM идеально подходит для работы в больших командах и на крупных проектах.

Хорошие практики:
- Используйте имена классов, которые чётко описывают функцию элемента, а не его внешний вид. Например, menu__item_disabled лучше, чем menu__item_gray.
- Не бойтесь создавать новые блоки. Это лучше, чем перегружать существующий блок излишней функциональностью.
- Избегайте каскадных стилей в BEM. Стилизуйте каждый элемент напрямую через его класс, это делает ваш CSS более предсказуемым.

Примеры из реальной жизни:
Давайте представим, что у нас есть блок product-card для карточки товара. Внутри него могут быть элементы как product-card__title для названия, так и product-card__price для цены. Если мы хотим выделить карточку товара на распродаже, мы добавляем модификатор product-card_sale.
/* Блок */
.product-card { ... }

/* Элементы */
.product-card__title { ... }
.product-card__price { ... }

/* Модификатор */
.product-card_sale { ... }


Заключение
BEM - это не только о нейминге, это о том, как организовать CSS вашего проекта, чтобы он был более понятным, масштабируемым и легким в поддержке.

#css

Читать полностью…

True Frontender

С понедельником! Сегодня поговорим о паттерне Builder(строитель). Он актуален, когда речь идет о создании сложных интерфейсов. Паттерн помогает разбить процесс на управляемые этапы, делая код чище и более организованным.

Что такое паттерн "Строитель"?
Строитель - это порождающий паттерн проектирования, который позволяет создавать сложные объекты, разделяя их создание на разные этапы. Это полезно, когда объект должен быть создан в несколько этапов или имеет множество возможных конфигураций.

Применение
Паттерн часто применяется для создания сложных UI компонентов. Например, при создании формы с множеством полей, кнопок и валидационных правил. Использование паттерна помогает упростить и структурировать процесс.

Преимущества:
Чистый код - использование этапов в процессе создания обеспечивает повышенную читаемость и облегчает поддержку кода.
Гибкость - возможность добавлять новые этапы и компоненты, не затрагивая уже написанный код.
Изоляция - сложные аспекты создания объектов удобно управляются и инкапсулируются.

Пример реализации
Допустим, у нас есть задача создания сложного интерактивного диалогового окна. Используя паттерн "Строитель", мы можем разделить этот процесс на этапы: создание основного контейнера, добавление кнопок, настройка обработчиков событий и так далее.
Пример с кодом на прикрепленном изображении.

В этом примере:
1. ModalBuilder - класс, реализующий паттерн "Строитель". Он позволяет пошагово создавать модальное окно с заголовком, содержимым и кнопками.
2. Методы setTitle, addButton, и setContent позволяют задавать соответствующие части модального окна.
3. Метод build создает и возвращает готовый элемент модального окна, который затем может быть добавлен в DOM.

Заключение
Паттерн "Строитель" является мощным инструментом для упрощения создания сложных объектов. Он обеспечивает чистоту и структурированность кода, делая его более поддерживаемым и расширяемым. Использование этого паттерна поможет вам управлять сложными задачами создания интерфейса и повысит качество вашего кода.

#patterns

Читать полностью…

True Frontender

С пятницей!
Наконец-то настал вечер пятницы, время, когда можно отдохнуть после долгой рабочей недели 🥳
Я полностью погрузился в работу и медленно, но верно приступаю к разработке большой стори. На выходных планирую уделить время созданию новых постов для вас. Надеюсь, посты на этой неделе были полезными для вас)

А как прошла ваша неделя, и чем вы планируете заниматься на выходных? Делитесь своими историями и планами в комментариях или просто поддержите этот пост реакциями ☺️

Всем хороших выходных 🏝

Читать полностью…

True Frontender

Всем ✌️! Сегодня я хочу поделиться с вами своими мыслями о !important в CSS, этой маленькой, но мощной детали, которая часто становится предметом горячих дебатов.

Что такое !important?
!important - это декларация, которая может быть добавлена к стилю, чтобы повысить его приоритет над другими объявлениями. Например:


p {
color: blue !important;
}

В этом случае, независимо от других селекторов или стилей, примененных к элементу <p>, цвет текста будет синим.

Когда использование !important оправдано
- Переопределение стилей сторонних библиотек или фреймворков иногда требует применения !important.
- В специфических случаях, когда необходимо гарантировать применение определенного стиля, !important может быть полезным.

Возможные проблемы при использовании !important
- Сложность поддержки кода увеличивается из-за усложнения стилевой логики.
- Конфликты стилей могут возникать из-за высокого приоритета стилей с !important.
- Отладка и тестирование стилей усложняются при наличии множества правил с !important.

Рекомендации по использованию !important
- Используйте !important только как крайнюю меру.
- Постарайтесь писать чистый и структурированный код, избегая необходимости в !important.
- Документируйте случаи использования !important, чтобы облегчить понимание и поддержку кода в будущем.

Заключение
!important это мощный инструмент, но его использование должно быть обоснованным и ограниченным. Осознанное применение !important поможет избежать многих проблем, связанных с поддержкой и масштабированием ваших проектов.

#css

Читать полностью…

True Frontender

Приветствую всех! Сегодня мы обсудим одну из фундаментальных тем в CSS - вес селекторов. Это поможет нам понять, как браузер решает, какие стили применять к элементу, когда имеется несколько конкурирующих правил.

Что такое вес селекторов?
Вес селектора определяет приоритетность стилей. Когда несколько селекторов претендуют на изменение одного и того же элемента, в игру вступает вес селекторов. Браузер следует правилам специфичности, чтобы определить, какие стили применять.

Вес селектора определяется на основе трех типов селекторов:
1. ID селекторы (#id) имеют самый высокий вес.
2. Классы, псевдоклассы и атрибуты (.class, :hover, [type="text"]) следуют за ID по весу.
3. Элементы и псевдоэлементы (например, div, ::after) имеют самый низкий вес.

Специфичность селектора можно представить в виде чисел, например: 0,1,0,0 для ID селектора, 0,0,1,0 для класса, и 0,0,0,1 для типа элемента. Но почему используются именно четыре цифры? Это связано с тем, что первая цифра отвечает за инлайновые стили (атрибут style в HTML), которые имеют самый высокий приоритет.

Правила подсчета:
Специфичность считается слева направо: инлайновые стили, затем ID, классы/псевдоклассы/атрибуты, и в конце элементы/псевдоэлементы. Более специфичный селектор переопределяет менее специфичные, даже если они объявлены позже.

Примеры:
- Селектор #header (вес 0,1,0,0) переопределит .main .header (вес 0,0,2,0) из-за наличия ID селектора.
- Селектор .button.active (вес 0,0,2,0) будет иметь больший приоритет, чем .button (вес 0,0,1,0) благодаря дополнительному классу.
- Селектор div span (вес 0,0,0,2) будет менее специфичным, чем .element (вес 0,0,1,0), несмотря на использование двух типов элементов.

Важные моменты:
- Универсальный селектор (*), комбинаторы (например, +, >) и отрицание (:not()) не влияют на вес.
- Стили, объявленные в атрибуте style HTML элемента, всегда имеют наивысший приоритет (за исключением !important).
- Использование !important в CSS объявлении может переопределить другие стили, независимо от их специфичности, но следует избегать его частого использования. В этом посте(тык) я делился своими мыслями на счет !important.

Почему это важно?
Понимание веса селекторов критически важно для эффективной работы с CSS. Это помогает в избежании конфликтов стилей и позволяет писать более предсказуемый и управляемый код.

Заключение
Итак, мы разобрали, как браузер определяет, какие стили нужно применить к элементу, на основе веса селекторов. Это знание помогает создавать стили, которые ведут себя ожидаемо и легче поддаются дебаггингу. Понимание специфичности селекторов позволяет вам избегать излишнего использования !important и обеспечивает более чистый, поддерживаемый код.

#css

Читать полностью…

True Frontender

Привет! Сегодня рассмотрим простой алгоритм сортировки. Сортировка вставками (Insertion Sort) — один из базовых, но в то же время эффективных алгоритмов сортировки. Этот метод часто используется из-за его простоты и эффективности на небольших массивах данных.

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

Пример из жизни
Представьте, что у вас есть рука, полная игральных карт. Вы берете карту и, просматривая уже отсортированные в руке карты, вставляете ее в нужное место. Точно так же работает сортировка вставками с массивами данных.

Преимущества:
- Простота реализации.
- Хорошая производительность на небольших массивах.
- Эффективна для массивов, которые уже частично отсортированы.
- Не требует дополнительной памяти.

Пример реализации:

function insertionSort(array) {
// Проходим по массиву, начиная со второго элемента,
// так как первый элемент уже считается отсортированным
for (let currentIndex = 1; currentIndex < array.length; currentIndex++) {
let currentValue = array[currentIndex]; // Текущий элемент для вставки
let previousIndex = currentIndex - 1; // Индекс предыдущего элемента

// Идём назад по массиву и ищем подходящее место для текущего элемента.
// Элементы, которые больше текущего значения, сдвигаем на один шаг вправо.
while (previousIndex >= 0 && array[previousIndex] > currentValue) {
array[previousIndex + 1] = array[previousIndex]; // Сдвигаем элемент вправо
previousIndex--; // Переходим к следующему элементу для сравнения
}

// Вставляем текущий элемент в найденную позицию.
array[previousIndex + 1] = currentValue;
}
return array;
}

// Пример использования
console.log(insertionSort([9, 1, 15, 4, 0]));


Когда использовать?
Сортировка вставками идеально подходит для небольших массивов или для массивов, которые уже частично отсортированы. Она также может быть полезна в ситуациях, где входные данные поступают последовательно и необходимо поддерживать отсортированное состояние данных.

Заключение
Сортировка вставками является хорошим инструментом. Она обеспечивает хорошую производительность на небольших массивах и проста в понимании и реализации.

#interview #javascript #algorithm

Читать полностью…

True Frontender

Всем привет ✌️
В этой статье мы погрузимся в Flexbox - мощный инструмент CSS для создания гибких и адаптивных макетов. Рассмотрим основные понятия и ключевые свойства.

-> Читать статью

#css

Читать полностью…

True Frontender

Всем привет! Хочу вместе с вами разобрать интересную задачу с собеседований: создание функции sum, которая позволяет выполнять цепочку вызовов вида sum(1)(2, 4)(3) и так далее. Эта задача является отличным тестом на понимание работы замыканий в JavaScript.

Требования к функции:
1. Функция должна корректно обрабатывать несколько последовательных вызовов с любым количеством аргументов.
2. Каждый вызов функции с аргументами должен добавлять эти значения к общей сумме.
3. Если функция вызвана без аргументов, она должна возвращать текущее значение суммы.

Решение:


function sum(...args) {
let total = args.reduce((acc, cur) => acc + cur, 0);

function innerSum(...innerArgs) {
if (!innerArgs.length) return total;
total += innerArgs.reduce((acc, cur) => acc + cur, 0);
return innerSum;
}

return innerSum;
}


В этом решении ключевым является использование замыкания для накопления суммы чисел между вызовами. Если innerSum вызывается без аргументов, она возвращает накопленный результат.

Пример использования:

console.log(sum(1)(2, 4)(3)()); // Выведет 10


Заключение
Такие задачи позволяют показать глубокое понимание важных концепций JavaScript и умение применять их в практических задачах.

А какие необычные или запоминающиеся задачи вам доводилось решать на собеседованиях?

#interview #javascript

Читать полностью…

True Frontender

Привет всем! Вероятно, вы уже прочитали множество статей о git, но я хочу предложить вам прочитать еще и мой пост) Сегодня я поделюсь своими мыслями о лучших практиках, а также предоставлю вам пару ссылок на интересные ресурсы.

Что такое Git?
Git - это система управления версиями, позволяющая отслеживать изменения в файлах и координировать работу над ними между несколькими людьми. Основное преимущество Git - его распределенная природа, позволяющая каждому участнику проекта иметь свою локальную копию репозитория.

Лучшие практики использования Git:
- Регулярно сохраняйте изменения, делая мелкие коммиты. Это упрощает навигацию по истории изменений и откат к более ранним версиям при необходимости.
- Пишите понятные и подробные сообщения к коммитам. Описательные сообщения помогают другим членам команды понять сделанные изменения и причины этих изменений.
- Работайте в отдельных ветках для новых функций или исправлений. Это предотвращает возможные конфликты в основной ветке кода и способствует более организованной работе.
- Понимайте разницу между merge и rebase для эффективного объединения изменений. merge соединяет ветки, сохраняя историю изменений, в то время как rebase переформатирует историю для более чистой линейной последовательности.
- Используйте файл .gitignore для исключения временных или локальных файлов из репозитория. Это предотвращает добавление ненужных или конфиденциальных файлов в общий репозиторий.

Полезные ссылки:
1. Learn Git Branching - интерактивный туториал, который помогает понять концепции ветвления и слияния в git.
2. Visualizing Git - можно посмотреть, как команды git влияют на структуру репозитория. Отлично подходит для визуализации сложных процессов в git.

#git

Читать полностью…

True Frontender

Привет! Сегодня хочу разобрать пользовательские события в JavaScript. Узнаем как эти события работают и как мы можем их использовать.

Что такое пользовательское событие?
Пользовательское событие - это событие, которое определено разработчиком, в отличие от стандартных событий, таких как click, mouseover и т.д. Это позволяет создавать более сложные и специфические сценарии взаимодействия в приложении.

Как создать пользовательское событие?
1. Использование конструктора Event. Это базовый способ создания пользовательских событий.

const event = new Event('customEvent', {
bubbles: true, // Событие всплывает
cancelable: true // Событие можно отменить
});

// Добавление слушателя для события
document.addEventListener('customEvent', function(e) {
console.log('Пользовательское событие активировано');
});

// Инициирование события
document.dispatchEvent(event);


2. Использование конструктора CustomEvent. CustomEvent - это расширение Event, которое позволяет передавать дополнительные данные с событием.
const customEvent = new CustomEvent('customEvent', {
detail: { message: 'Привет от CustomEvent' },
bubbles: true,
cancelable: true
});

document.addEventListener('customEvent', function(e) {
console.log('Сообщение: ', e.detail.message);
});

document.dispatchEvent(customEvent);


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

Заключение
Генерация пользовательских событий предоставляет мощный инструмент для создания интерактивных и динамичных приложений. Это позволяет создавать более сложные и настраиваемые сценарии взаимодействия, улучшая пользовательский опыт и функциональность приложений.

#javascript

Читать полностью…

True Frontender

Разница между useEffect и useLayoutEffect в React

Хуки useEffect и useLayoutEffect в React часто вызывают путаницу из-за их схожести. Оба хука предназначены для выполнения побочных эффектов в функциональных компонентах, но они имеют ключевые различия в тайминге их выполнения.

useEffect
useEffect используется для выполнения побочных эффектов в компоненте, таких как запросы данных, подписки или ручные изменения в DOM, которые не требуют немедленного выполнения и не блокируют визуальные обновления.

Особенности:
-
Выполняется после отрисовки и коммита компонента в DOM.
- Не блокирует визуальные обновления, что делает его идеальным для большинства побочных эффектов.
- Используется для взаимодействий с внешними API и выполнения асинхронных операций.

useLayoutEffect
useLayoutEffect работает аналогично useEffect, но вызывается синхронно после всех изменений DOM, но перед перерисовкой на экране. Это значит, что все изменения, выполненные в useLayoutEffect, будут отражены на экране сразу после его выполнения.

Особенности:
- Выполняется синхронно после всех изменений DOM, но до перерисовки.
- Используется для чтения или изменения DOM до того, как пользователь увидит обновления.
- Может вызывать блокировку визуальных обновлений, если содержит тяжелые вычисления.

Ключевые различия:
- useEffect выполняется после отрисовки компонента, позволяя выполнять побочные эффекты без блокировки визуальных обновлений, в то время как useLayoutEffect выполняется непосредственно после изменений в DOM и перед перерисовкой, что идеально подходит для задач, требующих немедленного чтения или изменения DOM.
- Использование useLayoutEffect может привести к заметным задержкам в визуальных обновлениях, особенно если в нем содержатся тяжелые вычисления, тогда как useEffect не оказывает такого влияния на процесс рендеринга.
- В большинстве случаев предпочтительнее использовать useEffect для обработки побочных эффектов, а useLayoutEffect следует использовать только тогда, когда необходимо синхронно взаимодействовать с DOM, например для измерения размеров элемента перед его отображением.

Заключение
Выбор между useEffect и useLayoutEffect зависит от требований к побочным эффектам в вашем компоненте. Хотя useEffect является наиболее часто используемым хуком для побочных эффектов из-за его не блокирующего поведения, useLayoutEffect предоставляет необходимую синхронность для определенных сценариев работы с DOM. Важно правильно выбирать между ними, чтобы обеспечить эффективную работу приложения и хороший пользовательский опыт.

#react

Читать полностью…
Subscribe to a channel