diff --git a/lessons/lesson22/lesson.md b/lessons/lesson22/lesson.md
index 00a9bec..b94aa07 100644
--- a/lessons/lesson22/lesson.md
+++ b/lessons/lesson22/lesson.md
@@ -407,4 +407,4 @@ alert(s(3)(4)(5)()); // 12
- [Debug Visualizer](https://marketplace.visualstudio.com/items?itemName=hediet.debug-visualizer)
- [Visualize JavaScript code execution](http://www.pythontutor.com/javascript.html#mode=edit)
- [JavaScript Visualizer (ES5)](https://ui.dev/javascript-visualizer/)
-- [Code to graph](https://crubier.github.io/code-to-graph/)
\ No newline at end of file
+- [Code to graph](https://crubier.github.io/code-to-graph/)
diff --git a/lessons/lesson23/lesson.md b/lessons/lesson23/lesson.md
index fbaba91..fd4955f 100644
--- a/lessons/lesson23/lesson.md
+++ b/lessons/lesson23/lesson.md
@@ -1,4 +1,5 @@
# Lesson 23
+
## OTUS Javascript Basic
### Разделение логики и представления
@@ -9,25 +10,26 @@
#### Цели занятия
-* Разобрать, как разделение кода на составляющие помогает с переиспользованием кода и его поддержкой (на простых примерах с запросами и DOM).
-* Узнать подходы: принцип единственной ответственности, представление, шаблонизация, сервисный слой, MVC и увидеть, как они выражаются в коде (используя то, что уже известно: функции, async/await, fetch, DOM, события).
-* На практике: маленькие примеры и рефакторинг (без классов — только функции).
+- Разобрать, как разделение кода на составляющие помогает с переиспользованием кода и его поддержкой (на простых примерах с запросами и DOM).
+- Узнать подходы: принцип единственной ответственности, представление, шаблонизация, сервисный слой, MVC и увидеть, как они выражаются в коде (используя то, что уже известно: функции, async/await, fetch, DOM, события).
+- На практике: маленькие примеры и рефакторинг (без классов — только функции).
#### **Компетенции:**
-* Применение метанавыков для обработки информации и принятия решений.
-* Умение структурировать программы.
+
+- Применение метанавыков для обработки информации и принятия решений.
+- Умение структурировать программы.
### План занятия
-* Введение: Зачем разделять — как "сортировка" в коде
-* Теория: Определения и подходы.
-* Маленькие примеры с запросами и DOM: "до/после"
-* Лайвкодинг: Плохой код → шаг за шагом в MVC
-* Итоги
+- Введение: Зачем разделять — как "сортировка" в коде
+- Теория: Определения и подходы.
+- Маленькие примеры с запросами и DOM: "до/после"
+- Лайвкодинг: Плохой код → шаг за шагом в MVC
+- Итоги
@@ -35,7 +37,6 @@
-
### Почему разделение — это легко и выгодно?
Вы уже знаете DOM, async/await и fetch, функции и объекты. Но в простых скриптах часто всё смешивается: fetch в обработчике клика + innerHTML там же. Результат — дубли, ошибки при изменении (сломал UI — сломал запрос).
@@ -55,16 +56,17 @@
### fetch в обработчике + DOM
```javascript
-document.getElementById('btn').addEventListener('click', async () => {
- const response = await fetch('https://jsonplaceholder.typicode.com/users/1');
+document.getElementById("btn").addEventListener("click", async () => {
+ const response = await fetch("https://jsonplaceholder.typicode.com/users/1");
const data = await response.json();
- document.getElementById('output').innerHTML = `
`;
});
}
renderDataAndFetch();
@@ -90,20 +96,19 @@ renderDataAndFetch();
Плохо: функция одновременно делает fetch и вставку в DOM, нарушается принцип единственной ответственности
-
### Шаблонизация
Определение: генерация HTML из заготовки и данных.
-Пример:
+Пример:
```js
for (let i = 0; i < data.length; i++) {
- html += '
' + data[i] + '
';
+ html += "
" + data[i] + "
";
}
```
@@ -113,15 +118,15 @@ for (let i = 0; i < data.length; i++) {
Функции для запросов и расчётов.
-Пример:
+Пример:
### сервисный fetch встроен в обработчик
```javascript
-document.getElementById('btn').addEventListener('click', async () => {
- const res = await fetch('https://jsonplaceholder.typicode.com/users/1');
+document.getElementById("btn").addEventListener("click", async () => {
+ const res = await fetch("https://jsonplaceholder.typicode.com/users/1");
const data = await res.json();
console.log(data);
});
@@ -129,7 +134,6 @@ document.getElementById('btn').addEventListener('click', async () => {
Плохо: нет переиспользования, каждый обработчик дублирует fetch, тестировать сложно
-
### Теория: MVC
@@ -142,12 +146,11 @@ Controller — связывает (addEventListener → model → view).
Преимущества: структура и масштабируемость.
-
### Примеры: "До" и "После"
-Используем fetch, addEventListener, innerHTML.
+Используем fetch, addEventListener, innerHTML.
Каждый пример: "плохой" (смешанный) и "хороший" (разделённый).
@@ -159,11 +162,11 @@ Controller — связывает (addEventListener → model → view).
```
@@ -174,13 +177,17 @@ document.getElementById('btn').addEventListener('click', showName);
### Пример 1: "После"
```javascript
-function getName() { return 'Алекс'; }
+function getName() {
+ return "Алекс";
+}
function renderName(name) {
- document.getElementById('name').innerHTML = `Имя: ${name}`;
+ document.getElementById("name").innerHTML = `Имя: ${name}`;
}
-document.getElementById('btn').addEventListener('click', () => renderName(getName()));
+document
+ .getElementById("btn")
+ .addEventListener("click", () => renderName(getName()));
```
Разделение: данные и представление отделены.
@@ -192,21 +199,20 @@ document.getElementById('btn').addEventListener('click', () => renderName(getNam
### Пример 2: "До" — список имён
```javascript
-const names = ['Маша', 'Петя'];
-let html = '
';
+const names = ["Маша", "Петя"];
+let html = "
";
for (let i = 0; i < names.length; i++) {
// Здесь потенциальная уязвимость:
- // если names[i] придёт из ненадёжного источника,
+ // если names[i] придёт из ненадёжного источника,
// вставка через + в innerHTML позволит выполнить HTML/JS
- html += '
' + names[i] + '
';
+ html += "
" + names[i] + "
";
}
-html += '
';
+html += "
";
// Здесь тоже уязвимость: innerHTML вставляет HTML напрямую
-document.getElementById('list').innerHTML = html;
-
+document.getElementById("list").innerHTML = html;
```
Недостаток: небезопасно.
@@ -216,16 +222,16 @@ document.getElementById('list').innerHTML = html;
### Пример 2: "После" — шаблон
```javascript
-const names = ['Маша', 'Петя'];
+const names = ["Маша", "Петя"];
function renderListSafe(items, containerId) {
const container = document.getElementById(containerId);
// создаём новый ul
- const ul = document.createElement('ul');
+ const ul = document.createElement("ul");
- items.map(name => {
- const li = document.createElement('li');
+ items.map((name) => {
+ const li = document.createElement("li");
li.textContent = name; // безопасно
ul.appendChild(li);
});
@@ -234,16 +240,13 @@ function renderListSafe(items, containerId) {
container.replaceChildren(ul);
}
-renderListSafe(names, 'list');
-
-
+renderListSafe(names, "list");
```
безопаснее
-
### Пример 3: "До" — расчёт суммы
```javascript
@@ -252,12 +255,13 @@ let sum = 0;
for (let i = 0; i < prices.length; i++) {
sum += prices[i];
}
-document.getElementById('total').innerText = 'Сумма: ' + sum;
+document.getElementById("total").innerText = "Сумма: " + sum;
```
Недостаток: логика и DOM смешаны.
+
### Пример 3: "После" — сервис
```javascript
@@ -265,7 +269,7 @@ function calculateSum(prices) {
return prices.reduce((total, price) => total + price, 0);
}
function renderTotal(sum) {
- document.getElementById('total').innerText = `Сумма: ${sum}`;
+ document.getElementById("total").innerText = `Сумма: ${sum}`;
}
renderTotal(calculateSum([100, 200]));
```
@@ -280,26 +284,27 @@ renderTotal(calculateSum([100, 200]));
```
Недостаток: асинхронный код и DOM в обработчике.
+
### Пример 4: "После" — сервис + View
```javascript
// Сервис: получает данные пользователя
async function getUser(id) {
const res = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`);
- if (!res.ok) throw new Error('Ошибка запроса');
+ if (!res.ok) throw new Error("Ошибка запроса");
return await res.json();
}
@@ -319,14 +324,15 @@ async function handleClick(id, containerId) {
}
// Пример привязки к кнопке
-document.getElementById('btn').addEventListener('click', () => handleClick(1, 'user'));
+document
+ .getElementById("btn")
+ .addEventListener("click", () => handleClick(1, "user"));
```
Код становится чище и надёжнее.
-
### Практика
@@ -335,22 +341,20 @@ document.getElementById('btn').addEventListener('click', () => handleClick(1, 'u
Основные выводы:
-* SRP, View, шаблоны, сервисы и MVC разделяют fetch и DOM.
-* Переиспользование: общие функции для разных мест.
+- SRP, View, шаблоны, сервисы и MVC разделяют fetch и DOM.
+- Переиспользование: общие функции для разных мест.
-### Домашнее задание: Смотрите на портале
-
+### Домашнее задание: Смотрите на портале
### Дополнительные материалы
-* SRP и SOLID в JavaScript
-* MVC без фреймворков
-* Шаблоны в JavaScript
-
+- SRP и SOLID в JavaScript
+- MVC без фреймворков
+- Шаблоны в JavaScript
diff --git a/lessons/lesson24/lesson.md b/lessons/lesson24/lesson.md
index ae23b01..6b4afa1 100644
--- a/lessons/lesson24/lesson.md
+++ b/lessons/lesson24/lesson.md
@@ -8,25 +8,25 @@
#### Цели занятия
-* Узнать подходы к проектированию частей приложения, которые упрощают поддержку и развитие.
-* Разобраться, почему важна низкая связанность и высокая связанность внутри модуля (cohesion), и как этого достичь.
-* Научиться выделять чистые функции и выносить побочные эффекты.
-* Освоить внедрение зависимостей (Dependency Injection) на функциях и модулях.
+- Узнать подходы к проектированию частей приложения, которые упрощают поддержку и развитие.
+- Разобраться, почему важна низкая связанность и высокая связанность внутри модуля (cohesion), и как этого достичь.
+- Научиться выделять чистые функции и выносить побочные эффекты.
+- Освоить внедрение зависимостей (Dependency Injection) на функциях и модулях.
#### Компетенции
-* Владение синтаксисом JavaScript (модули `import`/`export`).
-* Применение метанавыков для обработки информации и принятия решений в разработке.
-* Умение структурировать программы и проектировать API модулей.
+- Владение синтаксисом JavaScript (модули `import`/`export`).
+- Применение метанавыков для обработки информации и принятия решений в разработке.
+- Умение структурировать программы и проектировать API модулей.
#### Формат и результаты
-* Конспект занятия с примерами.
-* Длительность: 90 минут.
+- Конспект занятия с примерами.
+- Длительность: 90 минут.
@@ -47,10 +47,10 @@
Модуль — это логически связанный кусок кода с чёткой зоной ответственности и внешним API (экспортами). Делим код, чтобы:
-* уменьшить когнитивную нагрузку (проще понимать части);
-* переиспользовать и тестировать;
-* изолировать изменения (правка внутри модуля не ломает остальные);
-* управлять зависимостями явно.
+- уменьшить когнитивную нагрузку (проще понимать части);
+- переиспользовать и тестировать;
+- изолировать изменения (правка внутри модуля не ломает остальные);
+- управлять зависимостями явно.
@@ -58,16 +58,16 @@
```js
// app.js
-const form = document.querySelector('#form');
-const list = document.querySelector('#list');
+const form = document.querySelector("#form");
+const list = document.querySelector("#list");
const items = [];
-form.addEventListener('submit', (e) => {
+form.addEventListener("submit", (e) => {
e.preventDefault();
- const value = form.elements.namedItem('title').value;
+ const value = form.elements.namedItem("title").value;
items.push(value);
- list.innerHTML = items.map((x) => `