Глобальная регистрация компонента означает, что ты можешь использовать его в любом месте приложения, не подключая вручную. Это удобно для часто используемых элементов, таких как кнопки, формы или заголовки. Регистрация происходит один раз при запуске приложения, и после этого компонент доступен везде.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊14🤯3
В JavaScript нет встроенной поддержки интерфейсов, как в TypeScript, Java или C#. Однако, их можно заменить несколькими способами, в зависимости от задачи.
Можно описывать структуру объектов с помощью
@typedef
и @param
, что помогает при автодополнении и статическом анализе кода. /**
* @typedef {Object} User
* @property {string} name
* @property {number} age
*/
/**
* @param {User} user
*/
function printUser(user) {
console.log(`Имя: ${user.name}, Возраст: ${user.age}`);
}
const person = { name: "Alice", age: 30 };
printUser(person); // Работает!
Можно создать абстрактный класс с методами-заглушками, которые нужно реализовать в потомках.
class Animal {
constructor(name) {
if (new.target === Animal) {
throw new Error("Нельзя создать экземпляр абстрактного класса!");
}
this.name = name;
}
makeSound() {
throw new Error("Метод makeSound() должен быть переопределён!");
}
}
class Dog extends Animal {
makeSound() {
return "Гав-гав!";
}
}
const dog = new Dog("Бобик");
console.log(dog.makeSound()); // "Гав-гав!"
// const animal = new Animal("Лев"); // Ошибка!
Можно просто проверять, есть ли нужные методы и свойства у объекта перед использованием.
function useDevice(device) {
if (typeof device.turnOn !== "function") {
throw new Error("Объект должен иметь метод turnOn()");
}
device.turnOn();
}
const phone = { turnOn: () => console.log("Телефон включен!") };
useDevice(phone); // "Телефон включен!"
const invalidDevice = { power: true };
// useDevice(invalidDevice); // Ошибка: "Объект должен иметь метод turnOn()"
TypeScript добавляет поддержку интерфейсов в JavaScript.
interface User {
name: string;
age: number;
}
function printUser(user: User) {
console.log(`Имя: ${user.name}, Возраст: ${user.age}`);
}
const person: User = { name: "Alice", age: 30 };
printUser(person); // Работает!
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11
Forwarded from easyoffer
Я боялся, что провалю собеседование. Так появился easyoffer
Когда я только начинал искать первую работу программистом, меня пугала мысль, что я просто не смогу ответить на вопросы на собеседовании.
Типа… ты потратил месяцы на то, чтобы учиться, писал pet-проекты, собирал резюме, рассылаешь отклики — и всё может закончиться на одном-единственном вопросе, на который ты не знаешь ответ.
Я реально боялся.
Я смотрел видео mock-собеседований на YouTube, останавливал каждое, выписывал вопросы в Notion. Потом вручную писал к ним ответы. И потом ещё по нескольку раз перечитывал. Такой вот "тренажёр" на коленке.
📎 (там на картинке — один из моих реальных списков в Notion, ставь 🔥 если тоже так делал)
В какой-то момент я посчитал — у меня уже было выписано больше 500 вопросов. Я почувствовал ужас.
Потому что невозможно всё это зазубрить. А что, если спросят как раз тот, к которому я не успел подготовиться?..
Тогда и пришла идея
А что если понять, какие из вопросов встречаются чаще всего? Чтобы не учить всё подряд, а сфокусироваться на главном.
Так родился easyoffer.
Сначала — просто как пет-проект, чтобы показать в резюме и подготовиться к собесам. А потом оказалось, что он реально помогает людям. За первые месяцы его посетили сотни тысяч человек. И я понял: это больше, чем просто пет-проект.
Сейчас я делаю EasyOffer 2.0
И уже не один, а вместе с вами.
В новой версии будут:
– вопросы из реальных собесов, с фильтрацией по грейду, компании, типу интервью
– тренажёр с карточками (по принципу интервальных повторений — как в Anki)
– база задач с интервью
– тренажёр «реальное собеседование», чтобы отрепетировать как в жизни
Каждая фича упрощает и сокращает время на подготовку. Все эти штуки я бы мечтал иметь, когда сам готовился к собеседованиям.
Я делаю всё на свои деньги. Никаких инвесторов. Только вы и я.
Если вы хотите помочь — сейчас самое важное время.
Краудфандинг уже стартовал. Благодаря нему я смогу привлечь больше людей для разработки, сбору и обработки собеседований.
Все, кто поддержат проект до релиза, получат:
🚀 1 год PRO-доступа по цене месячной подписки. Его можно активировать в любое время, например когда начнете готовится к собесам.
➕ Доступ к закрытому бета-тесту
Поддержать 👉 https://planeta.ru/campaigns/easyoffer
Спасибо, что верите в этот проект 🙌
Когда я только начинал искать первую работу программистом, меня пугала мысль, что я просто не смогу ответить на вопросы на собеседовании.
Типа… ты потратил месяцы на то, чтобы учиться, писал pet-проекты, собирал резюме, рассылаешь отклики — и всё может закончиться на одном-единственном вопросе, на который ты не знаешь ответ.
Я реально боялся.
Я смотрел видео mock-собеседований на YouTube, останавливал каждое, выписывал вопросы в Notion. Потом вручную писал к ним ответы. И потом ещё по нескольку раз перечитывал. Такой вот "тренажёр" на коленке.
📎 (там на картинке — один из моих реальных списков в Notion, ставь 🔥 если тоже так делал)
В какой-то момент я посчитал — у меня уже было выписано больше 500 вопросов. Я почувствовал ужас.
Потому что невозможно всё это зазубрить. А что, если спросят как раз тот, к которому я не успел подготовиться?..
Тогда и пришла идея
А что если понять, какие из вопросов встречаются чаще всего? Чтобы не учить всё подряд, а сфокусироваться на главном.
Так родился easyoffer.
Сначала — просто как пет-проект, чтобы показать в резюме и подготовиться к собесам. А потом оказалось, что он реально помогает людям. За первые месяцы его посетили сотни тысяч человек. И я понял: это больше, чем просто пет-проект.
Сейчас я делаю EasyOffer 2.0
И уже не один, а вместе с вами.
В новой версии будут:
– вопросы из реальных собесов, с фильтрацией по грейду, компании, типу интервью
– тренажёр с карточками (по принципу интервальных повторений — как в Anki)
– база задач с интервью
– тренажёр «реальное собеседование», чтобы отрепетировать как в жизни
Каждая фича упрощает и сокращает время на подготовку. Все эти штуки я бы мечтал иметь, когда сам готовился к собеседованиям.
Я делаю всё на свои деньги. Никаких инвесторов. Только вы и я.
Если вы хотите помочь — сейчас самое важное время.
Краудфандинг уже стартовал. Благодаря нему я смогу привлечь больше людей для разработки, сбору и обработки собеседований.
Все, кто поддержат проект до релиза, получат:
🚀 1 год PRO-доступа по цене месячной подписки. Его можно активировать в любое время, например когда начнете готовится к собесам.
➕ Доступ к закрытому бета-тесту
Поддержать 👉 https://planeta.ru/campaigns/easyoffer
Спасибо, что верите в этот проект 🙌
🔥9👍1
CSS-свойство box-sizing принимает два значения:
- content-box – размер элемента считается по контенту, без учета padding и border.
- border-box – размер включает контент, padding и border, что облегчает расчет ширины/высоты.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🔥3❤1
В JavaScript для работы с датами можно использовать:
Date
– встроенный объект Библиотеку
Intl.DateTimeFormat
– для форматирования Библиотеки (
moment.js
, date-fns
, luxon
) – для удобной работы Создание даты
const now = new Date(); // Текущая дата и время
console.log(now); // Например: 2025-02-25T12:34:56.789Z
Способы создания даты
new Date(); // Текущая дата
new Date(2025, 1, 25); // 25 февраля 2025 (месяцы с 0)
new Date("2025-02-25"); // ISO строка
new Date(1708850400000); // Unix timestamp (в мс)
Получение значений
const date = new Date();
console.log(date.getFullYear()); // 2025
console.log(date.getMonth()); // 1 (февраль, потому что январь — 0)
console.log(date.getDate()); // 25
console.log(date.getDay()); // 2 (вторник, потому что воскресенье — 0)
console.log(date.getHours()); // Часы
console.log(date.getMinutes()); // Минуты
console.log(date.getSeconds()); // Секунды
console.log(date.getTime()); // Время в миллисекундах (Unix timestamp)
Изменение даты
const date = new Date();
date.setFullYear(2030);
date.setMonth(11); // Декабрь
date.setDate(31);
console.log(date); // 31 декабря 2030
Форматирование даты
const date = new Date();
console.log(date.toDateString()); // "Tue Feb 25 2025"
console.log(date.toISOString()); // "2025-02-25T12:34:56.789Z"
console.log(date.toLocaleString()); // Локальное представление
console.log(date.toUTCString()); // "Tue, 25 Feb 2025 12:34:56 GMT"
Форматирование с
Intl.DateTimeFormat
const date = new Date();
const formatter = new Intl.DateTimeFormat("ru-RU", {
year: "numeric",
month: "long",
day: "numeric",
weekday: "long",
});
console.log(formatter.format(date)); // "вторник, 25 февраля 2025 г."
date-fns
(легковесная альтернатива Moment.js) npm install date-fns
import { format, addDays } from "date-fns";
const now = new Date();
console.log(format(now, "dd.MM.yyyy HH:mm")); // 25.02.2025 15:30
console.log(addDays(now, 5)); // Дата + 5 дней
moment.js
(устаревший, но популярный)npm install moment
import moment from "moment";
const now = moment();
console.log(now.format("DD.MM.YYYY HH:mm")); // 25.02.2025 15:30
console.log(now.add(5, "days").format("DD.MM.YYYY")); // +5 дней
luxon
(современная альтернатива Moment.js)npm install luxon
import { DateTime } from "luxon";
const now = DateTime.now();
console.log(now.toFormat("dd.MM.yyyy HH:mm")); // 25.02.2025 15:30
console.log(now.plus({ days: 5 }).toFormat("dd.MM.yyyy")); // +5 дней
Разница между датами
const date1 = new Date("2025-02-25");
const date2 = new Date("2025-03-01");
const diff = date2 - date1; // Разница в миллисекундах
console.log(diff / (1000 * 60 * 60 * 24)); // Разница в днях (4)
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13
- Микротаски (microtasks) — выполняются сразу после текущего стека, до следующих макротасков. Сюда относятся:
- Promise.then
- MutationObserver
- queueMicrotask
- Макротаски (macrotasks) — ставятся в очередь и выполняются после микротасков. Сюда входят:
- setTimeout, setInterval
- setImmediate (в Node.js)
- I/O события
- события DOM
Таким образом, микротаски имеют более высокий приоритет, чем макротаски.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16🔥8🤯6😁1💊1
Общение между
iframe
и родительской страницей может происходить с помощью: Метода
postMessage
(лучший способ) Доступа к
window.frames
или window.parent
(если тот же домен) Передачи данных через
localStorage
или cookies
Метод
window.postMessage()
позволяет передавать сообщения между разными окнами (iframe
, popup
, другие вкладки) даже если они на разных доменах.*Код в
iframe
(child.html) // Отправляем сообщение родительскому окну
window.parent.postMessage({ type: "hello", data: "Привет, родитель!" }, "*");
Код в родительской странице (index.html)
window.addEventListener("message", (event) => {
console.log("Получено сообщение от iframe:", event.data);
});
*
в postMessage
означает, что сообщение отправляется любому домену. Лучше указывать конкретный, например: window.parent.postMessage({ type: "hello" }, "https://example.com");
Код в родительской странице (index.html)
const iframe = document.getElementById("myIframe");
// Ждём, когда iframe загрузится
iframe.onload = () => {
iframe.contentWindow.postMessage({ type: "greeting", data: "Привет, iframe!" }, "*");
};
Код в
iframe
(child.html) window.addEventListener("message", (event) => {
console.log("Получено сообщение от родителя:", event.data);
});
Если
iframe
и основная страница находятся на одном домене, можно обращаться к их window
напрямую.Родительская страница →
iframe
const iframe = document.getElementById("myIframe");
// Получаем объект `window` внутри `iframe`
iframe.contentWindow.document.body.style.backgroundColor = "lightblue";
iframe
→ Родительская страница console.log(window.parent.document.title); // Доступ к заголовку страницы
Можно сохранять данные в
localStorage
или cookies
, а другая сторона будет их читать. Запись в
localStorage
из iframe
localStorage.setItem("message", "Привет от iframe!");
Чтение
localStorage
в родительской странице console.log(localStorage.getItem("message")); // "Привет от iframe!"
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15
Для событий доступны модификаторы, которые управляют их поведением. Например, можно остановить распространение события вверх по DOM, предотвратить стандартное действие браузера, выполнить обработку только один раз или задать специальный порядок вызова. Это даёт более тонкий контроль над поведением событий в интерфейсе.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥4
version
(версия) – это числовой или текстовый идентификатор, который используется для обозначения определённого состояния кода, программы, библиотеки или API. Версия помогает понимать, какие изменения были внесены, и совместима ли текущая версия с предыдущими.
Наиболее распространённый стандарт версионирования – SemVer (Semantic Versioning). Он использует формат
MAJOR.MINOR.PATCH
Пример в
package.json
(Node.js-проекты): {
"name": "my-app",
"version": "1.2.3"
}
Команда для обновления версии в
package.json
npm version major # 2.0.0
npm version minor # 1.3.0
npm version patch # 1.2.4
При работе с REST API или GraphQL API тоже используют версии, чтобы не ломать старые клиенты.
https://api.example.com/v1/users
https://api.example.com/v2/users
В Git версиями называют теги (
tags
), привязанные к коммитам.git tag v1.0.0
git push origin v1.0.0
Чтобы посмотреть все версии
git tag
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
JavaScript — это язык программирования, а DOM — это объектная модель документа, предоставляемая браузером. JS используется для работы с DOM через его API.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊26👍8🤯5
В React при рендере списков (например, через
.map()
) каждому элементу необходимо передавать уникальный key
. Это помогает React оптимизировать перерисовку и правильно отслеживать изменения в списке. React использует виртуальный DOM и при обновлении сравнивает новый список с предыдущим.
Без
key
React не понимает, какие элементы изменились, удалились или добавились. Это может привести к неожиданному поведению, например, сбросу состояния или неправильному рендеру.
const users = ["Alice", "Bob", "Charlie"];
function UserList() {
return (
<ul>
{users.map((user, index) => (
<li key={user}>{user}</li> // Хорошо, если `user` уникален
))}
</ul>
);
}
Если не указать
key
, React выдаст предупреждение: Warning: Each child in a list should have a unique "key" prop.
Кроме того, при изменении списка возможны проблемы с перерисовкой
{users.map((user, index) => (
<input key={index} defaultValue={user} />
))}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥2😁2
Оба подхода используются в веб-разработке для обеспечения доступности и совместимости веб-приложений на разных устройствах и браузерах.
Сначала создаём простую, но рабочую версию сайта, которая работает на всех устройствах и браузерах. Затем добавляем улучшения (CSS-анимации, сложный JavaScript), которые работают только в современных браузерах.
Сначала создаём полнофункциональную версию с последними технологиями. Затем добавляем fallback'и (упрощённые версии) для старых браузеров.
Используем CSS Grid, но добавляем
@supports
для fallback'а на FlexboxПриложение на React, но показываем простой HTML, если JavaScript отключён.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10😁2
Мутировать объект можно:
- Через прямое присваивание (добавление, изменение, удаление свойств).
- С помощью методов:
- Object.assign() — копирование свойств.
- delete — удаление свойств.
- Прямое обращение к свойствам — для изменения значений.
- Добавление через obj[key] = value.
Также можно использовать Object.defineProperty() для более точного управления свойствами.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥3
Если пользователи захотят распечатать вашу веб-страницу, важно, чтобы она выглядела чисто и профессионально. Для этого используется CSS-медиа-правило
@media print
, которое позволяет задать специальные стили для печати. Вы можете задать стили, которые будут применяться только при печати
@media print {
body {
font-size: 12pt; /* Оптимальный размер шрифта */
color: black; /* Убираем цветной текст для экономии чернил */
background: none !important; /* Убираем фон */
}
}
Некоторые элементы (например, навигация, футер, кнопки) не нужны при печати, их можно скрыть
@media print {
nav, .sidebar, .ads, .button {
display: none; /* Скрываем ненужное */
}
}
Обычно страницы шире, чем лист бумаги. Можно задать
max-width
для удобства@media print {
body {
width: 100%;
max-width: 800px; /* Уменьшаем ширину */
margin: auto; /* Центрируем */
}
}
Заменяем цвета на чёрно-белые (экономия чернил)
@media print {
a {
color: black !important; /* Делаем ссылки чёрными */
text-decoration: underline; /* Добавляем подчёркивание */
}
}
При печати гиперссылки не работают, поэтому можно показать их адрес
@media print {
a::after {
content: " (" attr(href) ")"; /* Добавляем URL рядом со ссылкой */
font-size: 10pt;
color: gray;
}
}
Избегаем разрывов страниц в неудобных местах
@media print {
h1, h2, h3 {
page-break-after: avoid; /* Не разрываем страницу после заголовка */
}
p {
page-break-inside: avoid; /* Не разрываем абзац на две страницы */
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18
Forwarded from easyoffer
⏳ Осталось всего 14 дней до завершения краудфандинга
Сейчас самое подходящее время подключиться, если вы ждали или откладывали:
Все, кто поддержат проект сейчас, до релиза, получат:
🚀 PRO-доступ на 1 год по цене месячной подписки
➕ Бета-доступ к EasyOffer 2.0 (конец мая)
👉 Поддержать: https://planeta.ru/campaigns/easyoffer
Сейчас самое подходящее время подключиться, если вы ждали или откладывали:
Все, кто поддержат проект сейчас, до релиза, получат:
🚀 PRO-доступ на 1 год по цене месячной подписки
➕ Бета-доступ к EasyOffer 2.0 (конец мая)
👉 Поддержать: https://planeta.ru/campaigns/easyoffer
- Локальное состояние: useState, useReducer — работают внутри одного компонента.
- Context API — позволяет делиться данными между компонентами без пропсов.
- Redux — централизованное хранилище с actions и reducers, подходит для крупных приложений.
- Zustand — минималистичный менеджер, позволяет создавать глобальное состояние с простым API.
- Recoil — атомарная модель состояния, поддерживает асинхронность.
- MobX — реактивный подход с автообновлениями при изменении данных.
- Jotai, XState, React Query — решают разные задачи: управление атомами, конечными автоматами, загрузкой данных.
Выбор зависит от масштаба проекта и предпочтений команды.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊5👍4🔥2❤1
Если cookie содержит чувствительную информацию (например,
auth_token
), важно защитить его от доступа через JavaScript. Иначе злоумышленник может украсть его через XSS-атаку (Cross-Site Scripting). HttpOnly
делает cookie недоступным для JavaScript (document.cookie
). Set-Cookie: auth_token=abc123; HttpOnly; Secure; SameSite=Strict
Флаг
Secure
запрещает передачу cookie через HTTP, только HTTPS. Set-Cookie: auth_token=abc123; Secure
SameSite=Strict
или SameSite=Lax
защищает от подделки запросов (CSRF). Set-Cookie: auth_token=abc123; SameSite=Strict
Если возможно, используйте
Authorization: Bearer
заголовки вместо cookie. Authorization: Bearer abc123
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18🤔2❤1