Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
😁10 8
Привет! Готовы к короткой рабочей неделе? Давайте начнем ее с формошлепства.
Иногда дизайнеры рисуют сложные формы — поля в одном месте, кнопки в другом. Cамый простой вариант, который приходит в голову — обернуть всё в форму. Да, это работает, но в большинстве случаев это приведёт как минимум к багам, а максимум — к архитектурным проблемам.
Что делать?
Связать кнопку с формой через атрибут
Этот атрибут позволяет кнопке отправлять форму, даже если она расположена вне её, благодаря привязке через
Как это работает?
1.
2. Кнопка вне формы указывает на этот
3. Браузер связывает кнопку с формой и корректно обрабатывает
#HTML #BestPractices
Иногда дизайнеры рисуют сложные формы — поля в одном месте, кнопки в другом. Cамый простой вариант, который приходит в голову — обернуть всё в форму. Да, это работает, но в большинстве случаев это приведёт как минимум к багам, а максимум — к архитектурным проблемам.
Что делать?
Связать кнопку с формой через атрибут
form.Этот атрибут позволяет кнопке отправлять форму, даже если она расположена вне её, благодаря привязке через
id.
<form id="contactForm">
<input type="text" name="name" />
</form>
<!-- Кнопка вне формы -->
<button type="submit" form="contactForm">Сохранить</button>
Как это работает?
1.
<form> получает id.2. Кнопка вне формы указывает на этот
id через атрибут form.3. Браузер связывает кнопку с формой и корректно обрабатывает
submit.#HTML #BestPractices
🔥13👍1😁1
This media is not supported in your browser
VIEW IN TELEGRAM
Видели сайты с красивым скроллом фона? Это легко сделать самому, используя всего одно свойство CSS —
Демо и код тут: CodePen
Поддержка браузерами: CanIUse
#css
background-attachment: fixed;.Демо и код тут: CodePen
Поддержка браузерами: CanIUse
#css
🔥12👍6⚡1
Одна из распространённых ошибок при работе с React — вызов хуков внутри условий, циклов или вложенных функций 🖼️
Пример кода с ошибкой:
Ошибка:
Исправление ошибки:
Почему так происходит?
React запоминает порядок вызова хуков в компоненте и ожидает, что он всегда будет одинаковым. Если хук пропускается из-за условия, на следующем рендере React начинает привязывать хуки не к тем значениям.
Итог
Хуки должны вызываться всегда в одном порядке, без условий и вложенных блоков. Это базовое правило React, нарушение которого приводит к ошибкам в компонентах.
#react
Пример кода с ошибкой:
function Component({ show }) {
if (show) {
useEffect(() => {
console.log("Какой-то эффект");
}, []);
}
return <div>Тут что-то интересное!</div>;
}
Ошибка:
Invalid hook callИсправление ошибки:
function Component({ show }) {
useEffect(() => {
if (show) {
console.log("Какой-то эффект");
}
}, [show]);
return <div>Тут что-то интересное!</div>;
}
Почему так происходит?
React запоминает порядок вызова хуков в компоненте и ожидает, что он всегда будет одинаковым. Если хук пропускается из-за условия, на следующем рендере React начинает привязывать хуки не к тем значениям.
Итог
Хуки должны вызываться всегда в одном порядке, без условий и вложенных блоков. Это базовое правило React, нарушение которого приводит к ошибкам в компонентах.
#react
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥3
На майские беру небольшой перерыв 😋
Советую и вам отложить всю технику и как следует отдохнуть!)
Напоминаю, что у нас есть чат — @TrueFrontenderChat.
В нём можно задавать вопросы, помогать другим и предлагать идеи для будущих постов🐸
Хороших выходных!
Советую и вам отложить всю технику и как следует отдохнуть!)
Напоминаю, что у нас есть чат — @TrueFrontenderChat.
В нём можно задавать вопросы, помогать другим и предлагать идеи для будущих постов
Хороших выходных!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤13👍5 3
Привет! Небольшая задача с собеседования и отправляемся отдыхать 🏠
У нас есть следующий код:
Вопросы:
1. Что будет выведено на каждом шаге при выполнении кода в strict mode и без него?
2. Почему вывод отличается в разных случаях?
Разбор:
1. Метод
2. Метод
3. Метод
4. Метод
Ответ:
1.
2. В non-strict:
3.
4.
#interview #JavaScript
У нас есть следующий код:
const o = {
nameObject: "object o",
printName(a, b, c) {
console.log(this.nameObject);
},
};
// 1
o.printName();
// 2
let print = o.printName;
print();
// 3
print.call(o);
// 4
print.bind(o).call({ nameObject: "call name" });
Вопросы:
1. Что будет выведено на каждом шаге при выполнении кода в strict mode и без него?
2. Почему вывод отличается в разных случаях?
Разбор:
1. Метод
printName вызывается через объект o, и this указывает на сам объект o.2. Метод
printName присваивается переменной print и вызывается как обычная функция. Контекст this теряется, и в non-strict он указывает на глобальный объект (window), у которого нет свойства name. В strict моде this будет undefined, и попытка обращения к this.nameObject вызовет ошибку.3. Метод
call вызывает функцию с переданным контекстом. В данном случае, this указывает на объект o.4. Метод
bind создаёт новую функцию с привязанным контекстом o. После этого вызывается call, который пытается изменить контекст на новый объект, но bind уже установил контекст, и call не может его установить повторно.Ответ:
1.
"object o"2. В non-strict:
undefined. В strict: ошибка3.
"object o"4.
"object o"#interview #JavaScript
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13👀3
Привет! Отдохнули?) Начнем эту неделю с TypeScript. А вы знали, что в интерфейсы могут сливаться?
Пример:
В примере выше два интерфейса с одинаковым именем
Как это работает?
TypeScript объединяет все свойства из интерфейсов с одинаковыми именами в один интерфейс, позволяя вам динамически расширять интерфейсы без изменений в их исходной структуре.
Особенности:
1. Это работает только для интерфейсов, а не для типов(
2. Если два интерфейса имеют одинаковые свойства с разными типами, TypeScript выдаст ошибку
Пример ошибки:
В этом примере TypeScript не сможет объединить два интерфейса, потому что свойство
#typescript
Пример:
interface User {
name: string;
age: number;
}
interface User {
email: string;
}
const user: User = {
name: "Григорий",
age: 42,
email: "mail@example.com",
};
В примере выше два интерфейса с одинаковым именем
User сливаются в один, и объект user должен удовлетворять обоим интерфейсам.Как это работает?
TypeScript объединяет все свойства из интерфейсов с одинаковыми именами в один интерфейс, позволяя вам динамически расширять интерфейсы без изменений в их исходной структуре.
Особенности:
1. Это работает только для интерфейсов, а не для типов(
type).2. Если два интерфейса имеют одинаковые свойства с разными типами, TypeScript выдаст ошибку
Пример ошибки:
interface Product {
name: string;
price: number;
}
interface Product {
price: string; // Ошибка: Subsequent property declarations must have the same type.
}
В этом примере TypeScript не сможет объединить два интерфейса, потому что свойство
price имеет разные типы (number и string).#typescript
🔥10👍5⚡2
Я хорошо отдохнул на майских — и, честно говоря, мне это понравилось)
Посты могут выходить чуть реже, но качество контента не меняется. Хуже точно не станет🙃
Посты могут выходить чуть реже, но качество контента не меняется. Хуже точно не станет
Please open Telegram to view this post
VIEW IN TELEGRAM
❤11 5
Сегодня немного затронем работу с ошибками в 🖼️
Создание ошибок
Чтобы создать ошибку, нужно создать новый экземпляр класса
Мы создаём объект ошибки с сообщением и выбрасываем с помощью
Свойства
Каждый объект ошибки имеет несколько стандартных свойств:
-
-
-
Обработка ошибок
Использование
Ошибки не всегда должны прерывать выполнение приложения. С помощью
#JavaScript
Создание ошибок
Чтобы создать ошибку, нужно создать новый экземпляр класса
Error и передать сообщение в конструктор:
try {
throw new Error("Что-то пошло не так!");
} catch (error) {
console.error(error.message); // Что-то пошло не так!
}
Мы создаём объект ошибки с сообщением и выбрасываем с помощью
throw. Ошибка перехватывается в блоке catch, где мы можем вывести её сообщение.Свойства
Каждый объект ошибки имеет несколько стандартных свойств:
-
message — сообщение об ошибке.-
name — тип ошибки, по умолчанию это Error.-
stack — стек вызовов, который позволяет увидеть, откуда была вызвана ошибка.Обработка ошибок
Использование
throw и try...catch помогает контролировать ошибки в коде и избежать краша нашего приложения. Например, можно перехватить её и выполнить другие действия:
try {
const result = someFunction(); // Эта функция выбросит ошибку
} catch (error) {
console.error("Произошла ошибка:", error.message);
// Тут можно выполнить альтернативные действия
}
Ошибки не всегда должны прерывать выполнение приложения. С помощью
try...catch можно контролировать, как ошибки влияют на дальнейшие действия.#JavaScript
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7👍4👾2
Хотел бы обсудить сохранение постов.
Многие из нас сохраняют интересные посты. Но возвращаемся ли мы к этим сохранёнкам? Чаще всего — нет.
Почему так?
Потому что сохранение — это не запоминание. Это как положить книгу на полку и подумать, что ты уже её прочитал.
И главное мы почти никогда не возвращаемся к сохраненкам) Просто накапливаем.
А как лучше?
1. Если просто интересно — лучше прочитай сейчас, чем потом. Потом не наступит✅
2. Если хочешь попробовать — сразу пробуй🍺
3. Сохраняй меньше, но осознаннее🧠
4. Не сохраняй вообще, а читай и забывай — это тоже нормально✍️
Сохрани этот пост чтобы не потерять🚨
Ставь палец вверх если сохранил 👍
#BestPractices #Obsidian
Многие из нас сохраняют интересные посты. Но возвращаемся ли мы к этим сохранёнкам? Чаще всего — нет.
Почему так?
Потому что сохранение — это не запоминание. Это как положить книгу на полку и подумать, что ты уже её прочитал.
И главное мы почти никогда не возвращаемся к сохраненкам) Просто накапливаем.
А как лучше?
1. Если просто интересно — лучше прочитай сейчас, чем потом. Потом не наступит
2. Если хочешь попробовать — сразу пробуй
3. Сохраняй меньше, но осознаннее
4. Не сохраняй вообще, а читай и забывай — это тоже нормально
Сохрани этот пост чтобы не потерять
Ставь палец вверх если сохранил 👍
#BestPractices #Obsidian
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13😁7🔥3🤯1
Привет! Хотя регулярность постов и изменилась, неделя по-прежнему начинается с разбора задач с собеседований)
У нас есть пример типизированого массива:
И дана функция поиска по массиву, которую нужно типизировать:
Пример использования этой функции с массивом:
Задача:
Типизировать функцию
Решение:
1.
-
-
2. Параметры функции:
-
-
-
Вот и все) Мы типизировали функцию с помощью дженериков и сделали её универсальной для любых подобных массивов. Теперь мы можем гарантировать, что функция будет принимать только валидные аргументы.
В этом примере я не указал явно тип возвращаемого значения, так как TypeScript подтянет его автоматически. Но если функция будет меняться, лучше явно прописывать возвращаемый тип, чтобы избежать случайных ошибок в будущем.
#JavaScript #interview #typescript
У нас есть пример типизированого массива:
interface Student {
name: string;
age: number;
hasScar: boolean;
}
const students: Student[] = [
{ name: "Harry", age: 17, hasScar: true },
{ name: "Ron", age: 17, hasScar: false },
{ name: "Hermione", age: 16, hasScar: false },
];
И дана функция поиска по массиву, которую нужно типизировать:
function getBy(arr, prop, value) {
return arr.find(item => item[prop] === value) || null;
}
Пример использования этой функции с массивом:
const result = getBy(students, "name", "Hermione");
console.log(result);
Задача:
Типизировать функцию
getBy. Решение:
function getBy<T, K extends keyof T>(arr: T[], prop: K, value: T[K]) {
return arr.find(item => item[prop] === value) || null;
}
1.
<T, K extends keyof T> — дженерик:-
T — это универсальный тип, который представляет тип объекта внутри массива arr.-
K extends keyof T — означает, что K — это ключ объекта T. Тип keyof T — это объединение всех ключей объекта T. 2. Параметры функции:
-
arr: T[] — массив объектов типа T.-
prop: K — ключ, по которому будем искать совпадение.-
value: T[K] — значение, с которым будем сравнивать. Тип значения автоматически подтягивается из типа свойства prop. Вот и все) Мы типизировали функцию с помощью дженериков и сделали её универсальной для любых подобных массивов. Теперь мы можем гарантировать, что функция будет принимать только валидные аргументы.
В этом примере я не указал явно тип возвращаемого значения, так как TypeScript подтянет его автоматически. Но если функция будет меняться, лучше явно прописывать возвращаемый тип, чтобы избежать случайных ошибок в будущем.
#JavaScript #interview #typescript
👍8🔥4🤯4
В TypeScript 🖼️ есть два основных способа описания структуры данных — интерфейсы и типы. Когда и что выбирать?
Интерфейсы в TypeScript обычно используются для описания структуры объектов, особенно если они предполагают возможность расширения.
Их можно расширять с помощью
Типы идеально подходят для создания объединений и пересечений типов. Они пригодяся, когда нужно описать переменную, которая может быть одним из нескольких типов.
Пример объединения:
Пример пересечения:
Типы позволяют создавать псевдонимы для различных структур данных.
Что использовать?
Интерфейсы лучше использовать, когда:
— Нужно описать структуру объекта, которая может быть расширена.
— Работаете с объектами или классами, которые предполагают расширяемость.
Типы подходят, когда:
— Необходимо создать сложные структуры данных с объединениями или пересечениями.
— Нужно создавать псевдонимы для существующих типов или описывать более сложные типы данных.
#typescript #BestPractices
Интерфейсы в TypeScript обычно используются для описания структуры объектов, особенно если они предполагают возможность расширения.
Их можно расширять с помощью
extends, который позволяет создавать новые структуры на основе существующих.
interface Animal {
name: string;
}
interface Dog extends Animal {
breed: string;
}
const dog: Dog = {
name: 'Кнопка',
breed: 'Лабрадор'
};
Типы идеально подходят для создания объединений и пересечений типов. Они пригодяся, когда нужно описать переменную, которая может быть одним из нескольких типов.
Пример объединения:
type Result = 'success' | 'error';
const result: Result = 'success'; // Ок
const error: Result = 'failure'; // Будет ошибка
Пример пересечения:
type Person = { name: string };
type Worker = { job: string };
type Employee = Person & Worker;
const employee: Employee = {
name: 'Иван',
job: 'Frontender'
};
Типы позволяют создавать псевдонимы для различных структур данных.
type Coordinates = [number, number];
const point: Coordinates = [10, 20];
Что использовать?
Интерфейсы лучше использовать, когда:
— Нужно описать структуру объекта, которая может быть расширена.
— Работаете с объектами или классами, которые предполагают расширяемость.
Типы подходят, когда:
— Необходимо создать сложные структуры данных с объединениями или пересечениями.
— Нужно создавать псевдонимы для существующих типов или описывать более сложные типы данных.
#typescript #BestPractices
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10👍5👏2
Когда мы пишем приложения, важно обеспечить их стабильность, расширяемость и простоту поддержки. В этом посте узнаем про принципы SOLID, которые помогают с этим)
Используя SOLID-принципы, вы пишете код, который легче тестировать, поддерживать и развивать.
SOLID — это аббревиатура, которая объединяет 5 принципов:
S - Single Responsibility Principle (Принцип единой ответственности)
Каждый класс или компонент должен отвечать только за одну задачу. Это упрощает тестирование и отладку, потому что если что-то идет не так, вы точно знаете, какой класс или компонент за это отвечает. Такой подход также облегчает расширение приложения, так как изменение в одном месте не затронет другие части.
O - Open/Closed Principle (Принцип открытости/закрытости)
Классы должны быть открыты для расширения, но закрыты для модификации. Это означает, что вы можете добавлять новый функционал, не изменяя существующий код. Это достигается через использование абстракций, таких как интерфейсы и наследование.
L - Liskov Substitution Principle (Принцип подстановки Лисков)
Объекты базового класса должны быть заменяемыми объектами производного класса без нарушения корректности программы. Другими словами, наследуемые классы должны вести себя как их базовые классы, чтобы не ломать логику приложения.
I - Interface Segregation Principle (Принцип разделения интерфейсов)
Не стоит создавать универсальные интерфейсы, которые будут иметь множество методов, не используемых в разных классах. Лучше создавать несколько более специализированных интерфейсов. Это уменьшает зависимость классов и облегчает поддержку кода.
D - Dependency Inversion Principle (Принцип инверсии зависимостей)
Высокоуровневые модули не должны зависеть от низкоуровневых, а обе эти категории должны зависеть от абстракций. Это позволяет сделать код гибким и менее зависимым от конкретных реализаций.
Применение этих принципов поможет писать более чистый и поддерживаемый код, который будет легко расширяться и адаптироваться под изменения.
#BestPractices
Используя SOLID-принципы, вы пишете код, который легче тестировать, поддерживать и развивать.
SOLID — это аббревиатура, которая объединяет 5 принципов:
S - Single Responsibility Principle (Принцип единой ответственности)
Каждый класс или компонент должен отвечать только за одну задачу. Это упрощает тестирование и отладку, потому что если что-то идет не так, вы точно знаете, какой класс или компонент за это отвечает. Такой подход также облегчает расширение приложения, так как изменение в одном месте не затронет другие части.
O - Open/Closed Principle (Принцип открытости/закрытости)
Классы должны быть открыты для расширения, но закрыты для модификации. Это означает, что вы можете добавлять новый функционал, не изменяя существующий код. Это достигается через использование абстракций, таких как интерфейсы и наследование.
L - Liskov Substitution Principle (Принцип подстановки Лисков)
Объекты базового класса должны быть заменяемыми объектами производного класса без нарушения корректности программы. Другими словами, наследуемые классы должны вести себя как их базовые классы, чтобы не ломать логику приложения.
I - Interface Segregation Principle (Принцип разделения интерфейсов)
Не стоит создавать универсальные интерфейсы, которые будут иметь множество методов, не используемых в разных классах. Лучше создавать несколько более специализированных интерфейсов. Это уменьшает зависимость классов и облегчает поддержку кода.
D - Dependency Inversion Principle (Принцип инверсии зависимостей)
Высокоуровневые модули не должны зависеть от низкоуровневых, а обе эти категории должны зависеть от абстракций. Это позволяет сделать код гибким и менее зависимым от конкретных реализаций.
Применение этих принципов поможет писать более чистый и поддерживаемый код, который будет легко расширяться и адаптироваться под изменения.
#BestPractices
🔥15👍3
Please open Telegram to view this post
VIEW IN TELEGRAM
❤15 5