Telegram Web Link
Что такое вычисляемые свойства и как их использовать?

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

Вычисляемые свойства в объектных литералах задаются в квадратных скобках [].
let propName = 'name';
let person = {
[propName]: 'Alice'
};
console.log(person.name); // 'Alice'


Использование вычисляемых свойств
1. Динамическое имя свойства на основе переменной
let key = 'age';
let person = {
name: 'Alice',
[key]: 25
};

console.log(person.name); // 'Alice'
console.log(person.age); // 25


2. Использование выражений в качестве имен свойств
let i = 0;
let obj = {
['prop_' + ++i]: i,
['prop_' + ++i]: i,
['prop_' + ++i]: i
};

console.log(obj); // { prop_1: 1, prop_2: 2, prop_3: 3 }


3. Вложенные вычисляемые свойства
let prefix = 'user';
let index = 1;
let users = {
[prefix + index]: { name: 'Alice' },
[prefix + (index + 1)]: { name: 'Bob' }
};

console.log(users.user1.name); // 'Alice'
console.log(users.user2.name); // 'Bob'


4. Использование функции для вычисления имен свойств
function createKey(base, index) {
return base + index;
}

let obj = {
[createKey('key', 1)]: 'value1',
[createKey('key', 2)]: 'value2'
};

console.log(obj.key1); // 'value1'
console.log(obj.key2); // 'value2'


Применение в реальных сценариях
Создание объекта с динамическими ключами
Предположим, вам нужно создать объект для хранения оценок студентов, где ключи представляют собой имена студентов, а значения — их оценки.
let studentName1 = 'Alice';
let studentName2 = 'Bob';

let grades = {
[studentName1]: 85,
[studentName2]: 92
};

console.log(grades.Alice); // 85
console.log(grades.Bob); // 92


Использование вычисляемых свойств для формирования запросов

Допустим, у вас есть объект, представляющий параметры фильтра для поиска, и вы хотите динамически создавать ключи на основе выбранных фильтров.
function getFilterKey(filterName) {
return `filter_${filterName}`;
}

let filters = {};
filters[getFilterKey('age')] = 25;
filters[getFilterKey('location')] = 'New York';

console.log(filters); // { filter_age: 25, filter_location: 'New York' }


👉 @frontendInterview
Какое значение примет result?
Anonymous Quiz
24%
NaN
9%
undefined
8%
2
58%
6
1%
8
Позиционирование элементов с помощью JavaScript

Элементы на странице можно позиционировать не только с помощью стилей, но и с помощью JavaScript. В этой статье мы рассмотрим ситуации, когда это оправдано и как таким позиционированием пользоваться.

👉 @frontendInterview
Сохраняйте мегашпаргалку с полезными нейросетями на все случаи жизни от Сергея Фролова.

Вот самое крутое:
🤩Claude 3.7 Sonnet — мастхев для программистов
🤩Skyreels AI — превращает любой текст в длинное видео
🤩Openrouter — доступ ко всем ИИ
🤩Suno AI — своя музыка с нейросетью

Подпишись и находи для себя мощные нейросети бесплатно: https://www.tg-me.com/+poa2Q_32wcFhY2Yy
Please open Telegram to view this post
VIEW IN TELEGRAM
На пальцах про WebRTC на примере своего мессенджера

Сегодня разберёмся, как сделать видеозвонки — ту самую фичу, без которой сложно представить современное общение в 2025 году, на примере реализации мессенджера.

Для этого мы познакомимся с WebRTC — технологией, которая позволяет приложениям устанавливать прямое соединение друг с другом для обмена аудио, видео и другими данными. Это мощный, но местами капризный инструмент, который требует понимания архитектуры, сигналинга и сетевых нюансов вроде NAT и ICE.

В этой части мы:

- разберёмся, как работает WebRTC под капотом;
- напишем сигнальный сервер для обмена данными между участниками звонка;
- научим клиентов подключаться друг к другу и передавать медиапотоки;
- настроим поддержку STUN и TURN — чтобы звонки работали даже за NAT или в мобильных сетях;

Готовы? Поехали 🚀

👉 @frontendInterview
Как отследить демонтирование функционального компонента?

В функциональных компонентах React можно отслеживать демонтирование компонента с помощью хука useEffect. Когда компонент демонтируется, React вызывает функцию очистки, которую можно определить внутри useEffect.

import React, { useEffect } from 'react';

const MyComponent = () => {
useEffect(() => {
console.log('Component mounted');

// Функция очистки вызывается при демонтировании компонента
return () => {
console.log('Component will unmount');
};
}, []); // Пустой массив зависимостей означает, что эффект выполнится только при монтировании и демонтировании

return (
<div>
<p>My Component</p>
</div>
);
};

export default MyComponent;


Пример с реальным использованием
import React, { useEffect, useState } from 'react';

const WebSocketComponent = () => {
const [messages, setMessages] = useState([]);

useEffect(() => {
const socket = new WebSocket('ws://example.com/socket');

socket.onmessage = (event) => {
setMessages((prevMessages) => [...prevMessages, event.data]);
};

console.log('WebSocket connection opened');

return () => {
socket.close();
console.log('WebSocket connection closed');
};
}, []);

return (
<div>
<h1>WebSocket Messages</h1>
<ul>
{messages.map((message, index) => (
<li key={index}>{message}</li>
))}
</ul>
</div>
);
};

export default WebSocketComponent;


Открытие WebSocket соединения
const socket = new WebSocket('ws://example.com/socket');   


Обработка входящих сообщений
   socket.onmessage = (event) => {
setMessages((prevMessages) => [...prevMessages, event.data]);
};


Закрытие WebSocket соединения при демонтировании
   return () => {
socket.close();
console.log('WebSocket connection closed');
};


👉 @frontendInterview
React. Сборник рецептов. Практические приемы работы с фреймворком React

Книга посвящена практическому применению фреймворка React. Описано создание простых приложений и приложений со сложным интерфейсом, рассмотрены вопросы маршрутизации в приложениях и управление их состоянием. Даны примеры реализации интерактивного взаимодействия с пользователем, подключения к различным службам бэкенда, таким как REST и GraphQL, описана работа с библиотеками компонентов. Подробно рассматривается безопасность приложений, процесс их тестирования, даны советы по обеспечению доступности. Приводятся практические рекомендации по повышению производительности и созданию прогрессивных веб-приложений.

👉 @frontendInterview
Рост численности населения

В небольшом городе население в начале года составляет p0 = 1000 человек. Население регулярно увеличивается на 2 процента в год, и кроме того, в город приезжает 50 новых жителей в год. Сколько лет нужно городу, чтобы его население стало больше или равно p = 1200 жителей?

At the end of the first year there will be: 
1000 + 1000 * 0.02 + 50 => 1070 inhabitants

At the end of the 2nd year there will be:
1070 + 1070 * 0.02 + 50 => 1141 inhabitants (** number of inhabitants is an integer **)

At the end of the 3rd year there will be:
1141 + 1141 * 0.02 + 50 => 1213

It will need 3 entire years.


Более общие заданные параметры:
p0, percent, aug (inhabitants coming or leaving each year), p (population to equal or surpass)


Функция nb_year должна возвращать n количество полных лет, необходимых для получения численности населения, большей или равной p.

aug - целое число, percent - положительное или нулевое плавающее число, p0 и p - положительные целые числа (> 0)

Примеры:
nb_year(1500, 5, 100, 5000) -> 15
nb_year(1500000, 2.5, 10000, 2000000) -> 10


👉 @frontendInterview
Как уничтожить объект web worker?

В JavaScript, чтобы уничтожить объект Web Worker, необходимо использовать метод terminate(). Этот метод останавливает выполнение worker'а, освобождает связанные с ним ресурсы и завершает его работу. После вызова terminate() объект worker больше не может быть использован.

Зачем уничтожать Web Worker?
Web Worker позволяет выполнять тяжелые операции в фоновом потоке, не блокируя основной поток (UI-поток). Однако, если worker больше не нужен, он продолжает существовать и занимает ресурсы (память, процессорное время). Чтобы избежать утечек памяти и оптимизировать работу приложения, важно уничтожать worker, когда он больше не используется.

Как использовать `terminate()`?
Вы вызываете метод terminate() на экземпляре объекта worker. Это мгновенно останавливает выполнение фонового скрипта.
// Создаем worker
const myWorker = new Worker('worker.js');

// Выполняем какие-то операции через worker
myWorker.postMessage('Hello, worker!');

// Завершаем работу worker, когда он больше не нужен
myWorker.terminate();


Важно помнить
- После вызова terminate() worker полностью уничтожается и больше не может отправлять или получать сообщения.
- Если есть обработчики событий, привязанные к worker (например, onmessage), они автоматически удаляются.
- Доступ к worker после вызова terminate() не приведет к ошибке, но никакие операции через него больше работать не будут.
const worker = new Worker('worker.js');

// Отправляем сообщение
worker.postMessage('Start working');

// Завершаем работу worker
worker.terminate();

// Попытка отправить сообщение после уничтожения worker
worker.postMessage('Will this work?'); // Ничего не произойдет, worker уже завершен


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

👉 @frontendInterview
Каково значение свойства line-height у элемента section?
Anonymous Quiz
8%
60px
15%
40px
5%
120px
19%
80px
54%
20px
Как работает CSS will-change?

Свойство will-change позволяет заранее сообщить браузеру об изменениях (анимация, перемещение и т.д), которые могут произойти с элементом. Так браузер успеет оптимизировать выполнение этих изменений до того, как они произойдут. Это повышает скорость работы сайта.

will-change необходимо включить до изменения состояния элемента. Если применить это свойство в процессе изменения состояния, оно не успеет сработать и не даст никакого эффекта.

Такой код не сработает:
/* Изменение элемента происхожит при наведении курсора */
.element:hover {
/* нужно подготовиться к изменению, которое уже происходит, код не сработает */
will-change: transform;
transition: transform 2s;
transform: rotate(30deg) scale(1.5);
}


Если изменение элемента происходит при клике на него, will-change можно включать при наведении курсора на элемент. Это даёт браузеру время подготовиться до того, как произойдёт изменение .
.element {
/* правила */
transition: transform 1s ease-out;
}

.element:hover {
/* браузер начинает готовиться к изменению состояния */
will-change: transform;
}

.element:active {
/* происходит изменение состояния */
transform: rotateY(180deg);
}


Если изменение происходит при наведении курсора на элемент, то можно включать will-change при наведении на родительский элемент:
.element {
transition: opacity 0.3s linear;
}

/* включаем will-change для элемента, когда мышка наводится на его родительский элемент */
.parent:hover .element {
will-change: opacity;
}

/* применение изменения, когда мышка наведена на элемент */
.element:hover {
opacity: 0.5;
}


🛠 Рекомендуется отключать will-change сразу после того, как закончится изменение элемента. Поэтому лучше назначать это свойство через JavaScript. Если назначить его через CSS, его невозможно будет убрать после выполнения изменения и оно будет продолжать расходовать ресурсы.

Иногда will-change допускается назначать через CSS. Это относится к часто используемым элементам (например, анимация кнопки или сайдбара) и к изменениям, которые происходят на странице постоянно (например, анимация, которая происходит при движении курсора мышки).

👉 @frontendInterview
Что делать, если устал быть фрилансером, а в найм не берут?

«Я мечтал быть свободным, а стал уставшим неврастеником» — такую фразу мне сказал Сергей на консультации. За его плечами — 4 года успешного фриланса в digital-сфере. В его кейсах — известные бренды, хорошие деньги и полная свобода. А ещё — отсутствие выходных, тревога, скачки дохода и выгорание. Он захотел «назад в офис», но получал вежливые отказы или полный игнор.

К сожалению, это довольно частая история. Фриланс — крутая ступень развития, но далеко не всегда конечная точка. Многие рано или поздно хотят вернуться в найм, и сталкиваются с рядом проблем. Давайте разберёмся, почему так происходит, и что с этим делать.

Почему люди вообще устают от фриланса? Причин на то несколько.

👉 @frontendInterview
Можно ли перезапустить остановленный promise?

Нет, Promise в JavaScript нельзя перезапустить. Промисы являются одноразовыми: после того как они переходят в одно из состояний — выполнен (resolved) или отклонён (rejected) — их состояние больше не может измениться. Это одно из ключевых свойств промисов.

Почему нельзя перезапустить Promise?
- Промис, как только выполняется, становится иммутабельным. После выполнения (resolve) или отклонения (reject), он остаётся в этом состоянии навсегда.
- Промисы предназначены для представления единственного результата асинхронной операции. Их дизайн не предполагает повторного запуска той же самой асинхронной логики.

const myPromise = new Promise((resolve, reject) => {
resolve('Done!');
});

myPromise.then((result) => console.log(result)); // "Done!"

// Даже если вы попытаетесь вызвать resolve или reject снова, ничего не произойдет
myPromise.then((result) => console.log(result)); // "Done!" (результат уже закеширован)


Что делать, если нужно "перезапустить" асинхронную операцию?
Если вы хотите выполнить операцию заново, вместо "перезапуска" Promise нужно создать новый Promise или использовать функцию, которая возвращает новый Promise каждый раз.
function createPromise() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve('Я новый промис!'), 1000);
});
}

// Первый вызов
createPromise().then((result) => console.log(result)); // "Я новый промис!"

// "Перезапуск"
createPromise().then((result) => console.log(result)); // "Я новый промис!" (новый промис создан)


Как это сделать с использованием `async/await`?

Это синтаксический сахар над промисами. Если вам нужно "перезапустить" асинхронную операцию, просто вызовите асинхронную функцию ещё раз.
async function fetchData() {
return new Promise((resolve) => {
setTimeout(() => resolve('Данные загружены!'), 1000);
});
}

async function main() {
const data1 = await fetchData();
console.log(data1); // "Данные загружены!"

const data2 = await fetchData(); // "Перезапуск" fetchData
console.log(data2); // "Данные загружены!"
}

main();


Повторная попытка выполнения промиса (ретрай)
Если вам нужно повторно попытаться выполнить операцию (например, в случае неудачи), можно реализовать "ретрай". Это особенно полезно для операций вроде сетевых запросов.
function fetchDataWithRetry(retries) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() > 0.7) { // 70% шансов на ошибку
resolve('Данные успешно загружены!');
} else {
reject('Ошибка загрузки данных');
}
}, 1000);
}).catch((error) => {
if (retries > 0) {
console.log(`Повторная попытка... Осталось: ${retries}`);
return fetchDataWithRetry(retries - 1); // Рекурсивный вызов
} else {
throw error; // Если попытки исчерпаны, выбрасываем ошибку
}
});
}

fetchDataWithRetry(3)
.then((data) => console.log(data))
.catch((error) => console.error(error));


👉 @frontendInterview
2025/07/01 11:06:37
Back to Top
HTML Embed Code: