├── .gitignore
├── 01.JS(core)
├── 0.Введение в JS (core).md
├── 1.Лексическое окружение и ОВ.md
├── 2.Hoisting(поднятие).md
├── 3.Функции и аргументы.md
├── 4.Замыкания.md
└── 5.Общие вопросы.md
├── 02.Переменные: let,const,var
├── 0.Введение в переменные: let, const, var.md
└── 1.Различие переменных и работа.md
├── 03.Работа с типами данных
├── 0.Введение в работу с типами данных.md
├── 1.Примитивные типы данных.md
├── 2.Приведение типов.md
├── 3.Строгое и нестрогое равенство.md
└── 4.Приведение объектов к примитивам.md
├── 04.Циклы: плюсы, минусы и особенности
├── 0.Введение в циклы: плюсы, минусы и особенности.md
└── 1.Основы циклов.md
├── 05.Стрелочные функции
├── 0.Основы стрелочных функций.md
├── 1.Arguments нет в стрелочных функциях.md
├── 2.This в стрелочных функциях.md
└── 3.Когда стрелочные функции не походят.md
├── 06.Деструктуризация
├── 0.Введение в деструктуризацию.md
└── 1.Основы и работа в коде.md
├── 07.Объекты, контекст
├── 0.Основы объектов и работы с контекстом.md
└── 1.Использование методов контекста.md
├── 08.Асинхронный код
├── 0.Введение в асинхронный код.md
├── 1.Асинхронное программирование.md
├── 2.Работа с Promise и методами.md
├── 3.Плюсы и минусы Promise, async-await, callback.md
├── 4.Async и Await.md
├── 5.Асинхронные запросы.md
└── 6.Обработка ошибок.md
├── 09.Итераторы и генераторы
├── 0.Введение в итератор и генератор.md
├── 1.Использование итератора.md
└── 3.Механизм итерации и работа генераторов.md
├── 10.Базовые операторы
├── 0.Введение в базовые операторы.md
├── 1.Операторы сравнения.md
├── 2.Операторы присваивания.md
├── 3.Операторы инкремент и декремент.md
├── 4.Операторы (&&) и (||).md
├── 5.Операторы (??) и (?.).md
├── 6.Тернарный оператор.md
└── 7.Оператор (&).md
├── 11.JS-Browser
├── 7.Всплытие событий в DOM.md
├── 0.Введение в JavaScript для браузера.md
├── 1.событие в JavaScript и Event Handling.md
├── 2.Методы доступа к DOM-элементам.md
├── 3.Добавление, удаление и замена элементов.md
├── 4.Доступ к атрибутам элемента DOM.md
├── 5.Разница между innerText и innerHTML.md
├── 6.Обзор методов применения стилей через JS.md
└── 8.Ввиртуальный DOM и как он связан с реальным DOM.md
├── 12.Инструменты разработчика Chrome
├── 0.Введение в инструменты разработчика.md
├── 01.DevTools для анализа.md
├── 02.Анализ производительности страницы в DevTools.md
├── 03.Медленный интернет в DevTools.md
├── 04.Моделирование мобильных устройств в DevTools.md
├── 05.Использование вкладки "Network" в DevTools.md
├── 06.Как анализировать утечки памяти в DevTools.md
├── 07.Application в DevTools.md
├── 08.Заголовки серверного запроса DevTools.md
├── 09.Измерения выполнения кода с DevTools.md
├── 10.доступность веб-страницы с помощью DevTools.md
├── 11.Cookies и работа с ними в DevTools.md
└── 12.Доступность веб-страницы с DevTools.md
├── 13.Кэширование в Веб
├── 0.Введение в кэширование.md
├── 1.Работа кэширование в браузере.md
├── 2.Кэширование на стороне клиента и сервера.md
├── 3.localStorage и sessionStorage для кэширования.md
├── 4.Контроль кэширования статических ресурсов.md
├── 5. sw для кэширования в офлайн-режиме.md
└── 6.Проблемы с кэширование.md
├── 14.LocalStorage, SessionStorage и Cookies
├── 0.Введение в хранилище.md
├── 1.В каких случаях использовать ls, ss, cookies.md
├── 3.Меры безопасности при использовании Cookies.md
└── 4.Кросс-доменные запросы.md
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | /.idea
--------------------------------------------------------------------------------
/01.JS(core)/0.Введение в JS (core).md:
--------------------------------------------------------------------------------
1 | # 📌 Что такое JavaScript Core?
2 | **JavaScript Core (JS Core)** — это фундаментальные концепции языка JavaScript, которые определяют его поведение, структуру и работу с данными. Это основы, без которых невозможно писать сложные и эффективные программы.
3 |
4 | ---
5 |
6 | ### ❓ Зачем изучать JS Core?
7 | Изучение JS Core важно для:
8 | - Глубокого понимания работы движка JavaScript.
9 | - Оптимизации кода и повышения производительности.
10 | - Избежания распространённых ошибок.
11 | - Подготовки к собеседованиям и улучшения навыков программирования.
12 |
13 | ---
14 |
15 | ### 🔹 Основные темы JS Core:
16 | 1. **Лексическое окружение и ОВ (Область Видимости)**
17 | - Как работает область видимости переменных.
18 | - Замыкания и их применение.
19 |
20 | 2. **Hoisting (поднятие)**
21 | - Как интерпретатор поднимает объявления `var`, `let`, `const` и функций.
22 | - Разница между `var`, `let` и `const` в контексте hoisting.
23 |
24 | 3. **Функции и аргументы**
25 | - Различные способы объявления функций (Function Declaration, Expression, Arrow Functions).
26 | - Передача аргументов, значение `this`, параметры по умолчанию.
27 |
28 | 4. **Замыкания**
29 | - Что такое замыкание и как оно работает.
30 | - Практическое применение в разработке.
31 |
32 | 5. **Общие вопросы**
33 | - Частые вопросы на собеседованиях по JS Core.
34 | - Как улучшить понимание основ JavaScript.
35 |
36 | ---
37 |
38 | ### 🎯 Почему это важно?
39 | Знание JS Core позволяет писать более предсказуемый, эффективный и оптимизированный код. Это основа для работы с современными фреймворками (React, Vue, Angular) и написания сложных веб-приложений.
40 |
41 | ---
42 |
--------------------------------------------------------------------------------
/02.Переменные: let,const,var/0.Введение в переменные: let, const, var.md:
--------------------------------------------------------------------------------
1 | # ❓ Что такое переменные?
2 | **Переменные в JavaScript** — это именованные контейнеры для хранения данных. Они позволяют программам запоминать и использовать значения в процессе работы.
3 |
4 | ---
5 |
6 | ### ❓ Зачем нужны переменные?
7 | Переменные позволяют:
8 | - Хранить данные для последующего использования.
9 | - Изменять значения в процессе выполнения программы.
10 | - Улучшать читаемость и удобство кода.
11 | - Создавать динамические приложения, работающие с пользовательским вводом и API.
12 |
13 | ---
14 |
15 | ### 📌️ Различия между `let`, `const` и `var`
16 |
17 | #### 🔹 1. `var` (устаревший способ объявления переменных)
18 | **Особенности:**
19 | - Поддерживается всеми версиями JavaScript.
20 | - Можно переопределять и изменять значение.
21 | - Доступна во всей функции (или глобально, если объявлена вне функций).
22 | - Подвержена "hoisting" (поднятию), что может вызывать ошибки.
23 |
24 | #### ✍ Пример:
25 | ```js
26 | console.log(a); // undefined (hoisting)
27 | var a = 10;
28 | console.log(a); // 10
29 | ```
30 |
31 | #### 🔹 2. `let` (современный способ объявления переменных)
32 | **Особенности:**
33 | - Можно изменять значение, но нельзя переобъявить в одной области видимости.
34 | - Блоковая область видимости ({}).
35 | - Не подвергается "hoisting" так же, как `var` (не инициализируется автоматически).
36 |
37 | #### ✍ Пример:
38 | ```js
39 | let b = 20;
40 | b = 30; // Можно изменить
41 | console.log(b); // 30
42 | ```
43 |
44 | #### 🔹 3. `const` (для неизменяемых значений)
45 | **Особенности:**
46 | - Нельзя изменить или переопределить значение.
47 | - Блоковая область видимости.
48 | - Используется для хранения неизменяемых данных.
49 |
50 | #### ✍ Пример:
51 | ```js
52 | const c = 40;
53 | c = 50; // Ошибка! Нельзя изменить значение const
54 | ```
55 |
56 | ---
57 |
58 | ### ❓ Когда использовать `let`, `const` и `var`?
59 | - **Используйте `const`**, если значение не должно изменяться.
60 | - **Используйте `let`**, если значение будет изменяться.
61 | - **Избегайте `var`**, так как он может вызывать непредсказуемые ошибки.
62 |
63 | ---
64 |
65 | ### ❓ Почему важно изучать переменные?
66 | Знание разницы между `let`, `const` и `var` помогает:
67 | - Писать чистый, предсказуемый код.
68 | - Избегать ошибок, связанных с областью видимости и `hoisting`.
69 | - Работать с современным JavaScript, используя лучшие практики.
70 |
71 | ---
72 |
73 | 🎉 Правильное использование переменных делает код более понятным и устойчивым к ошибкам, что особенно важно при работе в команде или создании сложных приложений.
74 |
75 | ---
--------------------------------------------------------------------------------
/03.Работа с типами данных/0.Введение в работу с типами данных.md:
--------------------------------------------------------------------------------
1 | # ❓ Что такое типы данных?
2 | **Тип данных** — это характеристика значения, которая определяет, какие операции можно выполнять с этим значением. В JavaScript существует два основных типа данных: **примитивные** и **объектные**.
3 |
4 | ---
5 |
6 | ### ❓ Зачем изучать типы данных?
7 | Понимание типов данных важно для:
8 | - Написания предсказуемого кода без неожиданных ошибок.
9 | - Оптимизации работы с памятью.
10 | - Грамотного использования приведения типов.
11 | - Правильной работы со сравнением значений.
12 |
13 | ---
14 |
15 | ### 🔹 Основные темы:
16 | 1. **Примитивные типы данных**
17 | - Включают `number`, `string`, `boolean`, `null`, `undefined`, `bigint`, `symbol`.
18 | - Имеют неизменяемые значения (immutable).
19 |
20 | 2. **Приведение типов**
21 | - Неявное и явное преобразование значений между различными типами (`Number()`, `String()`, `Boolean()`).
22 | - Потенциальные ошибки при автоматическом приведении.
23 |
24 | 3. **Строгое и нестрогое равенство**
25 | - Разница между `==` и `===`.
26 | - Когда использовать строгие сравнения и зачем.
27 |
28 | 4. **Приведение объектов к примитивам**
29 | - Как объекты превращаются в строки, числа и логические значения.
30 | - Методы `toString()`, `valueOf()`, `Symbol.toPrimitive()`.
31 |
32 | ---
33 |
34 | ### ❓ Почему это важно?
35 | **Работа с типами данных** — основа любого JavaScript-кода. Ошибки, связанные с типами, могут привести к неожиданному поведению программы. Знание типов данных помогает писать более чистый, безопасный и оптимизированный код.
36 |
37 | ---
38 |
--------------------------------------------------------------------------------
/04.Циклы: плюсы, минусы и особенности/0.Введение в циклы: плюсы, минусы и особенности.md:
--------------------------------------------------------------------------------
1 | # Что такое циклы в JavaScript?
2 |
3 | **Циклы** — это конструкции, которые позволяют выполнять одни и те же действия многократно, пока выполняется заданное условие. Они помогают автоматизировать рутинные задачи и делают код более кратким и удобочитаемым.
4 |
5 | ## 📌 Зачем нужны циклы?
6 |
7 | Циклы широко применяются в программировании для:
8 | - Перебора массивов и объектов.
9 | - Повторения операций до достижения нужного результата.
10 | - Выполнения асинхронных операций (например, ожидание данных из API).
11 | - Генерации динамических элементов в интерфейсе.
12 |
13 | ---
14 |
15 | ## 🔹 Основные виды циклов в JavaScript
16 |
17 | ### `for` — когда известно количество повторений
18 |
19 | ```javascript
20 | for (let i = 0; i < 5; i++) {
21 | console.log(i);
22 | }
23 | ```
24 |
25 | ### `while` — выполняется, пока условие истинно
26 |
27 | ```javascript
28 | let i = 0;
29 | while (i < 5) {
30 | console.log(i);
31 | i++;
32 | }
33 | ```
34 |
35 | ### `do...while` — выполняет тело хотя бы один раз
36 |
37 | ```javascript
38 | let i = 0;
39 | do {
40 | console.log(i);
41 | i++;
42 | } while (i < 5);
43 | ```
44 |
45 | ### `for...in` — перебирает свойства объекта
46 |
47 | ```javascript
48 | const obj = { a: 1, b: 2, c: 3 };
49 | for (let key in obj) {
50 | console.log(key, obj[key]);
51 | }
52 | ```
53 |
54 | ### `for...of` — используется для итерируемых объектов (массивы, строки и т. д.)
55 |
56 | ```javascript
57 | const arr = [10, 20, 30];
58 | for (let num of arr) {
59 | console.log(num);
60 | }
61 | ```
62 | ---
63 |
64 | ## Преимущества циклов:
65 |
66 | - Автоматизация повторяющихся операций.
67 | - Сокращение кода и повышение читаемости.
68 | - Гибкость: работа с массивами, объектами, API.
69 |
70 | ## Возможные недостатки:
71 |
72 | - Возможность бесконечного выполнения (если не задать условие выхода).
73 | - Неоптимизированный цикл может потреблять много ресурсов.
74 | - В асинхронном коде лучше использовать `map`, `forEach` или `Promise`.
75 |
76 | ---
77 |
78 | ## 🎯 Итог
79 |
80 | Циклы — это важная часть программирования, без которой сложно представить работу с массивами, объектами и динамическими интерфейсами. Освоив их, вы сможете писать более эффективный и структурированный код! 🚀
81 |
82 | ---
83 |
84 |
85 |
86 | ## 🏆 ЗАДАЧИ
87 |
88 | ### 📌 Задача 1: Вывести числа от 1 до 10
89 |
90 | Напишите цикл, который выводит числа от 1 до 10 в консоль.
91 |
92 | ✍ Решение
93 |
94 | ```js
95 | for (let i = 1; i <= 10; i++) {
96 | console.log(i);
97 | }
98 | ```
99 |
100 |
101 | ---
102 |
103 | ### 📌 Задача 2: Сумма чисел от 1 до `n`
104 |
105 | Напишите программу, которая находит сумму всех чисел от 1 до `n`.
106 |
107 | ✍ Решение
108 |
109 | ```js
110 | function sumToN(n) {
111 | let sum = 0;
112 | for (let i = 1; i <= n; i++) {
113 | sum += i;
114 | }
115 | return sum;
116 | }
117 |
118 | console.log(sumToN(10)); // 55
119 | ```
120 |
121 |
122 | ---
123 |
124 | ### 📌 Задача 3: Обход массива с числами
125 |
126 | Дан массив `[5, 10, 15, 20, 25]`. Выведите в консоль каждый его элемент.
127 |
128 | ✍ Решение
129 |
130 | ```js
131 | const numbers = [5, 10, 15, 20, 25];
132 | for (let num of numbers) {
133 | console.log(num);
134 | }
135 | ```
136 |
137 |
138 | ---
139 |
140 | ### 📌 Задача 4: Вывести только чётные числа от 1 до 20
141 |
142 | **Задание:** Используйте цикл, чтобы вывести в консоль только чётные числа от 1 до 20.
143 |
144 | ✍ Решение
145 |
146 | ```js
147 | for (let i = 2; i <= 20; i += 2) {
148 | console.log(i);
149 | }
150 | ```
151 |
152 |
153 | ---
154 |
155 |
--------------------------------------------------------------------------------
/05.Стрелочные функции/3.Когда стрелочные функции не походят.md:
--------------------------------------------------------------------------------
1 | # ❓ Когда стрелочные функции не подходят?
2 |
3 | Стрелочные функции в JavaScript — это удобный и лаконичный способ записи функций, особенно когда нужно сохранить контекст `this` из внешней области видимости. Но есть случаи, когда их использование не просто нецелесообразно, а может привести к ошибкам. Ниже — список ситуаций, когда стрелочные функции **не могут** заменить обычные.
4 |
5 | ---
6 |
7 | ## 🔹 1. Методы объектов
8 |
9 | Стрелочные функции **не имеют собственного `this`**, поэтому при использовании их как методы объектов `this` не будет указывать на сам объект.
10 |
11 | ```javascript
12 | const obj = {
13 | value: 42,
14 | showValue: function() {
15 | console.log(this.value); // 42
16 | },
17 | showValueArrow: () => {
18 | console.log(this.value); // undefined
19 | }
20 | };
21 |
22 | obj.showValue(); // 42
23 | obj.showValueArrow(); // undefined
24 | ```
25 |
26 | Используйте **обычные функции** для методов, чтобы `this` корректно указывал на объект.
27 |
28 | ---
29 |
30 | ## 🔹 2. Конструкторы
31 |
32 | Стрелочные функции **нельзя использовать как конструкторы**. Попытка сделать это приведет к ошибке.
33 |
34 | ```javascript
35 | const Person = (name) => {
36 | this.name = name;
37 | };
38 | const john = new Person('John'); // ❌ TypeError: Person is not a constructor
39 | ```
40 |
41 | Используйте `function Person(name) { ... }` или `class`.
42 |
43 | ---
44 |
45 | ## 🔹 3. `arguments`
46 |
47 | Стрелочные функции **не имеют собственного объекта `arguments`**, что делает их неудобными в функциях с переменным числом параметров.
48 |
49 | ```javascript
50 | function normalFunction() {
51 | console.log(arguments); // [1, 2, 3]
52 | }
53 | const arrowFunction = () => {
54 | console.log(arguments); // ❌ ReferenceError
55 | };
56 |
57 | normalFunction(1, 2, 3);
58 | arrowFunction(1, 2, 3);
59 | ```
60 |
61 | Если нужен `arguments`, используйте обычную функцию.
62 |
63 | ---
64 |
65 | ## 🔹 4. Обработчики событий
66 |
67 | В обработчиках DOM-событий `this` должен ссылаться на сам элемент, вызвавший событие. У стрелочных функций этого нет.
68 |
69 | ```javascript
70 | const button = document.querySelector('button');
71 |
72 | button.addEventListener('click', function() {
73 | console.log(this); // 🔍 button
74 | });
75 |
76 | button.addEventListener('click', () => {
77 | console.log(this); // ❌ не button
78 | });
79 | ```
80 |
81 | Для событий — **обычные функции**.
82 |
83 | ---
84 |
85 | ## 🔹 5. Методы классов
86 |
87 | Хотя стрелочные функции можно использовать внутри методов класса, **в качестве самих методов они не рекомендуются** из-за неочевидного поведения `this`.
88 |
89 | ```javascript
90 | class MyClass {
91 | constructor(value) {
92 | this.value = value;
93 | }
94 | method() {
95 | return () => {
96 | console.log(this.value); // Работает, но может запутать
97 | };
98 | }
99 | }
100 |
101 | const instance = new MyClass(10);
102 | const func = instance.method();
103 | func(); // 10
104 | ```
105 |
106 | Используйте обычные методы класса для ясности и поддержки.
107 |
108 | ---
109 |
110 | ## 🔹 6. Нельзя изменить `this` у стрелочной функции
111 |
112 | У стрелочных функций невозможно изменить `this` через `call`, `apply` или `bind`. Они навсегда «привязаны» к `this`, из области, где были созданы.
113 |
114 | ```javascript
115 | const arrow = () => {
116 | console.log(this.value);
117 | };
118 |
119 | const obj = { value: 100 };
120 | arrow.call(obj); // ❌ this не изменится
121 | ```
122 |
123 | Для гибкого управления `this` — только обычные функции.
124 |
125 | ---
126 |
127 | ## 🎯 Итог
128 |
129 | Используйте стрелочные функции:
130 | - в **коротких коллбэках** (`map`, `filter`, `forEach` и т.д.),
131 | - когда нужно **сохранить `this` из внешнего контекста**,
132 | - в **вложенных функциях**.
133 |
134 | Но избегайте их:
135 | - для методов объектов,
136 | - в конструкторах,
137 | - если нужен `arguments`,
138 | - при работе с DOM-событиями,
139 | - когда важно управлять `this` вручную.
140 |
141 | ---
142 |
143 | Отлично, вот тебе подборка **практических задач** на тему "Когда стрелочные функции не подходят", с пояснениями и выводами — чтобы закрепить материал 💡
144 |
145 | ---
146 |
147 | ## 🏆 ЗАДАЧИ
148 |
149 | ---
150 |
151 | ### 📌 Задача 1: Метод объект
152 | ❓ Что выведет код ниже?
153 |
154 | ```javascript
155 | const user = {
156 | name: "Alice",
157 | sayName: () => {
158 | console.log(this.name);
159 | }
160 | };
161 |
162 | user.sayName();
163 | ```
164 |
165 |
166 | ✅ Вывод
167 |
168 | ```javascript
169 | undefined
170 | ```
171 |
172 | Объяснение:
173 |
174 | Стрелочная функция не создает свой `this`, она берет его из внешнего контекста. В этом случае `this` — это глобальный объект (`window` в браузере), а не `user`.
175 |
176 | Методы объектов должны быть обычными функциями.
177 |
178 |
179 | ---
180 |
181 | ### 📌 Задача 2: Конструктор
182 | ❓ Что произойдет при выполнении кода?
183 |
184 | ```javascript
185 | const Animal = (name) => {
186 | this.name = name;
187 | };
188 |
189 | const dog = new Animal("Buddy");
190 | ```
191 |
192 |
193 | ✅ Вывод
194 |
195 | ```
196 | TypeError: Animal is not a constructor
197 | ```
198 |
199 | Объяснение:
200 |
201 | Стрелочные функции нельзя вызывать с `new`.
202 |
203 | Конструкторы создаются только с обычными функциями или через `class`
204 |
205 |
206 | ---
207 |
208 | ### 📌 Задача 3: arguments в стрелочной функции
209 | ❓ Что выведет этот код?
210 |
211 | ```javascript
212 | const showArgs = () => {
213 | console.log(arguments);
214 | };
215 |
216 | showArgs(1, 2, 3);
217 | ```
218 |
219 |
220 | ✅ Вывод
221 |
222 | ```
223 | ReferenceError: arguments is not defined
224 | ```
225 |
226 | Объяснение:
227 |
228 | У стрелочных функций нет своего `arguments`
229 |
230 | Используй обычные функции, если тебе нужно `arguments`
231 |
232 |
233 | ---
234 |
235 | ### 📌 Задача 4: Обработчик событий
236 | ❓ Какой будет результат?
237 |
238 | ```html
239 |
240 |
246 | ```
247 |
248 |
249 | ✅ Вывод
250 |
251 | ```javascript
252 | undefined
253 | ```
254 |
255 | Объяснение:
256 |
257 | Стрелочная функция не привязывает `this` к кнопке — она берет его из внешнего контекста (в браузере это `window`, у которого нет `id`).
258 |
259 | Для событий лучше использовать обычную функцию, если нужен доступ к элементу через `this`.
260 |
261 |
262 | ---
263 |
264 | ### 📌 Задача 5: bind и стрелочная функция
265 | ❓ Что выведет код?
266 |
267 | ```javascript
268 | const obj = {
269 | value: 99
270 | };
271 |
272 | const arrowFunc = () => {
273 | console.log(this.value);
274 | };
275 |
276 | const boundFunc = arrowFunc.bind(obj);
277 | boundFunc();
278 | ```
279 |
280 |
281 | ✅ Вывод
282 |
283 | ```javascript
284 | undefined
285 | ```
286 |
287 | Объяснение:
288 |
289 | Метод `bind()` не работает со стрелочными функциями — `this` всё равно берется из области, где была определена функция.
290 |
291 | Используй обычные функции, если ты собираешься изменять `this`.
292 |
293 |
294 | ---
295 |
296 | ### 📌 Задача 6: Использование стрелки внутри метода
297 | ❓ Что выведет код?
298 |
299 | ```javascript
300 | const counter = {
301 | count: 0,
302 | start: function() {
303 | setInterval(() => {
304 | this.count++;
305 | console.log(this.count);
306 | }, 1000);
307 | }
308 | };
309 |
310 | counter.start();
311 | ```
312 |
313 |
314 | ✅ Вывод
315 |
316 | ```
317 | Будет увеличиваться count: 1, 2, 3, ...
318 | ```
319 |
320 | Объяснение:
321 |
322 | Стрелочная функция внутри `setInterval` сохраняет `this` из метода `start`, и `this.count` правильно указывает на `counter`.
323 |
324 | Вложенные стрелочные функции хороши для сохранения `this`.
325 |
326 |
327 | ---
328 |
329 | 🎉 Эти задачи помогут закрепить основные идеи, связанные с отсутствием `arguments` в стрелочных функциях и другими ограничениями их использования. Они подчеркивают важные различия между стрелочными и обычными функциями, а также помогают лучше понять, как контекст `this` и доступ к `arguments` влияют на структуру, стиль и читаемость кода.
330 |
331 | ---
--------------------------------------------------------------------------------
/06.Деструктуризация/0.Введение в деструктуризацию.md:
--------------------------------------------------------------------------------
1 | # ❓ Что такое деструктуризация?
2 | **Деструктуризация** — это удобный способ извлекать значения из массивов и объектов и присваивать их переменным с помощью краткого и понятного синтаксиса. Она была добавлена в JavaScript в ES6 и позволяет значительно упростить работу с данными.
3 |
4 | ---
5 |
6 | ### ❓ Зачем нужна деструктуризация?
7 |
8 | **Деструктуризация** помогает разработчикам:
9 |
10 | 1. **Уменьшить количество кода** — позволяет избегать многократного обращения к объекту или массиву.
11 | 2. **Повысить читаемость** — код становится более понятным и лаконичным.
12 | 3. **Извлекать нужные данные сразу** — можно достать только нужные свойства, не обращаясь ко всему объекту.
13 | 4. **Задавать значения по умолчанию** — можно предусмотреть запасные значения на случай, если данных нет.
14 |
15 | ---
16 |
17 | ### ❓ Как работает деструктуризация?
18 |
19 | #### 🔹 Деструктуризация массива
20 | Позволяет извлекать элементы массива и присваивать их переменным:
21 | ```javascript
22 | const numbers = [1, 2, 3];
23 | const [first, second, third] = numbers;
24 | console.log(first); // 1
25 | console.log(second); // 2
26 | console.log(third); // 3
27 | ```
28 | Можно пропускать элементы:
29 | ```javascript
30 | const [, second, third] = numbers;
31 | console.log(second); // 2
32 | console.log(third); // 3
33 | ```
34 | ---
35 |
36 | #### 🔹 Деструктуризация объекта
37 | Позволяет извлекать свойства объекта и присваивать их переменным:
38 | ```javascript
39 | const user = { name: "Alice", age: 25 };
40 | const { name, age } = user;
41 | console.log(name); // "Alice"
42 | console.log(age); // 25
43 | ```
44 |
45 | Можно задавать псевдонимы переменных:
46 | ```javascript
47 | const { name: userName, age: userAge } = user;
48 | console.log(userName); // "Alice"
49 | console.log(userAge); // 25
50 | ```
51 |
52 | ---
53 |
54 | ### ❓ Почему важно изучать деструктуризацию?
55 | Деструктуризация — это важный инструмент современного JavaScript, который широко используется в:
56 | - **Работе с API** (например, обработка JSON-ответов);
57 | - **Разработке React, Vue, Angular** (Props, State, Hooks);
58 | - **Функциях с объектами параметров** (чтобы избежать лишнего обращения к свойствам);
59 | - **Оптимизации кода** (код становится чище и понятнее).
60 |
61 | ---
62 |
63 | 🎉 Знание деструктуризации помогает писать современный, удобочитаемый и эффективный код, что делает её обязательной темой для изучения каждым JavaScript-разработчиком.
64 |
65 | ---
--------------------------------------------------------------------------------
/07.Объекты, контекст/0.Основы объектов и работы с контекстом.md:
--------------------------------------------------------------------------------
1 | # 📌 Основы работы с методами `call`, `apply` и `bind`
2 |
3 | Методы `call`, `apply` и `bind` являются важными инструментами в JavaScript для управления контекстом (`this`) при вызове функций. Давайте коротко затронем каждый из них, чтобы понять, когда и почему они могут быть полезны.
4 |
5 | ## 🔹 1. **Метод `call`**
6 | Метод `call` вызывает функцию немедленно, передавая ей контекст `this` и аргументы по отдельности.
7 |
8 | **Синтаксис:**
9 | ```javascript
10 | func.call(thisArg, arg1, arg2, ...);
11 | ```
12 |
13 | **Пример:**
14 | ```javascript
15 | function greet(greeting) {
16 | console.log(greeting + ', ' + this.name);
17 | }
18 | const person = { name: 'Alice' };
19 | greet.call(person, 'Hello'); // Выведет: Hello, Alice
20 | ```
21 |
22 | - Используется, когда необходимо передать параметры в функцию по одному, сразу же вызвав её с определённым контекстом.
23 |
24 | ## 🔹 2. **Метод `apply`**
25 | Метод `apply` работает аналогично методу `call`, но аргументы передаются в виде массива.
26 |
27 | **Синтаксис:**
28 | ```javascript
29 | func.apply(thisArg, [argsArray]);
30 | ```
31 |
32 | **Пример:**
33 | ```javascript
34 | function greet(greeting) {
35 | console.log(greeting + ', ' + this.name);
36 | }
37 | const person = { name: 'Bob' };
38 | greet.apply(person, ['Hi']); // Выведет: Hi, Bob
39 | ```
40 |
41 | - Подходит, когда передается массив аргументов, и необходимо вызвать функцию с определённым контекстом.
42 |
43 | ## 🔹 3. **Метод `bind`**
44 | Метод `bind` не вызывает функцию немедленно, а возвращает новую функцию, которая при вызове будет иметь привязанный контекст и предустановленные аргументы.
45 |
46 | **Синтаксис:**
47 | ```javascript
48 | const boundFunction = func.bind(thisArg, arg1, arg2, ...);
49 | ```
50 |
51 | **Пример:**
52 | ```javascript
53 | function greet(greeting) {
54 | console.log(greeting + ', ' + this.name);
55 | }
56 | const person = { name: 'Charlie' };
57 | const greetCharlie = greet.bind(person, 'Hey');
58 | greetCharlie(); // Выведет: Hey, Charlie
59 | ```
60 |
61 | - Используется, когда нужно заранее подготовить функцию с контекстом и аргументами, а вызывать её будете позже.
62 |
63 | ### ❓ Когда использовать `call`, а когда `apply`?
64 |
65 | - Используйте **`call`**, когда передаете аргументы функции по одному.
66 | - Используйте **`apply`**, когда передаете аргументы в виде массива.
67 |
68 | ### ❓ Когда и зачем использовать `bind`?
69 |
70 | Метод `bind` полезен, когда вам нужно создать новую функцию с привязанным контекстом для дальнейшего использования, например, в коллбэках или обработчиках событий.
71 |
72 | Представьте, что вы хотите сохранить контекст в обработчике события:
73 | ```javascript
74 | const button = document.getElementById('myButton');
75 | const person = { name: 'Alice' };
76 |
77 | function handleClick() {
78 | console.log('Button clicked by: ' + this.name);
79 | }
80 |
81 | // Без bind контекст будет указывать на DOM элемент, а не на person
82 | button.addEventListener('click', handleClick.bind(person));
83 | ```
84 |
85 | ### ❓ Что происходит с `this` при использовании `call`, `apply`, и `bind`?
86 |
87 | - В методах `call` и `apply` контекст (`this`) задается первым аргументом.
88 | - В методе `bind` контекст задается при создании новой функции, которая будет использовать его при каждом вызове.
89 |
90 | ### ❓ Как стрелочные функции работают с `call`, `apply`, и `bind`?
91 |
92 | Стрелочные функции не имеют своего собственного контекста `this`. Они наследуют `this` от окружающего контекста. Следовательно:
93 |
94 | - Стрелочные функции игнорируют методы `call`, `apply`, и `bind`. Их контекст всегда определяется внешней областью видимости, а не через эти методы.
95 |
96 | ### ❓ Что произойдет, если вызвать `bind` дважды?
97 |
98 | ```javascript
99 | const obj1 = { name: 'Alice' };
100 | const obj2 = { name: 'Bob' };
101 |
102 | const greet = function(greeting) {
103 | console.log(greeting + ', ' + this.name);
104 | };
105 |
106 | const greetAlice = greet.bind(obj1);
107 | const greetBob = greetAlice.bind(obj2);
108 |
109 | greetBob('Hello'); // Выведет: Hello, Alice
110 | ```
111 |
112 | В этом примере, несмотря на второй `bind`, контекст останется привязан к `obj1`. Это происходит потому, что `bind` всегда возвращает новую функцию, и она сохраняет контекст из первого вызова.
113 |
114 | ---
115 |
116 | ## 🎯 Итог
117 |
118 | - **`call`** и **`apply`** используются для немедленного вызова функций с привязанным контекстом, но в разных форматах передачи аргументов.
119 | - **`bind`** полезен для создания новых функций с фиксированным контекстом.
120 | - Стрелочные функции не работают с этими методами, поскольку их контекст всегда наследуется из окружающей области видимости.
121 |
122 | ---
123 |
--------------------------------------------------------------------------------
/08.Асинхронный код/0.Введение в асинхронный код.md:
--------------------------------------------------------------------------------
1 | # 📌 Что такое асинхронное программирование?
2 | **Асинхронное программирование** подход к выполнению кода, при котором некоторые операции выполняются в фоновом режиме, не блокируя основной поток выполнения программы. В JavaScript это особенно важно, так как он работает в однопоточном режиме и не может выполнять несколько задач одновременно.
3 |
4 | В асинхронном программировании операции, которые занимают много времени (например, загрузка данных с сервера или работа с файлами), выполняются отдельно, а основной код продолжает свою работу. Когда операция завершена, система уведомляет об этом и выполняет соответствующие обработчики.
5 |
6 | ---
7 |
8 | ### ❓ Зачем нужен асинхронный код?
9 | Асинхронный код решает важные проблемы производительности и удобства работы с программами. Он нужен для:
10 |
11 | 1. **Работы с сетью:**
12 | - Запросы к API (`fetch`, `XMLHttpRequest`, `axios`)
13 | - Загрузка данных с сервера и их обработка
14 |
15 | 2. **Работы с базами данных:**
16 | - Получение и запись данных в базы данных (например, MongoDB, Firebase)
17 |
18 | 3. **Файловых операций:**
19 | - Чтение и запись файлов в Node.js
20 |
21 | 4. **Работы с таймерами:**
22 | - `setTimeout`, `setInterval` для отложенного выполнения кода
23 |
24 | 5. **Оптимизации пользовательского интерфейса (UI):**
25 | - Долговременные вычисления можно выполнять в Web Workers, чтобы не замораживать страницу
26 |
27 | ---
28 |
29 | ### ❓ Как работает асинхронный код в JavaScript?
30 | JavaScript использует **Event Loop** (цикл событий) для обработки асинхронных задач. Когда встречается асинхронная операция, она отправляется в очередь выполнения, а основной поток продолжает работать с остальным кодом. Когда асинхронная операция завершается, её обработчик попадает в очередь событий и выполняется, когда основной поток освободится.
31 |
32 | #### Пример синхронного кода:
33 | ```js
34 | console.log("Начало");
35 | console.log("Конец");
36 | ```
37 | #### Выведет:
38 | ```
39 | Начало
40 | Конец
41 | ```
42 |
43 | #### Пример асинхронного кода:
44 | ```js
45 | console.log("Начало");
46 | setTimeout(() => {
47 | console.log("Асинхронный код");
48 | }, 1000);
49 | console.log("Конец");
50 | ```
51 | #### Выведет:
52 | ```
53 | Начало
54 | Конец
55 | Асинхронный код
56 | ```
57 |
58 | ---
59 |
60 | ### ❓ Зачем изучать асинхронный код?
61 | **Асинхронное программирование** — это ключевая часть JavaScript. Его понимание необходимо для:
62 |
63 | - Разработки современных веб-приложений (AJAX, API-запросы)
64 | - Работы с серверами и базами данных (Node.js, Express, MongoDB)
65 | - Создания производительных интерфейсов (React, Vue, Angular)
66 | - Оптимизации производительности (минимизация блокировки основного потока)
67 |
68 | ---
69 |
70 | ## 🎯 Итог
71 |
72 | Без асинхронного программирования веб-приложения были бы медленными и плохо отзывчивыми. Поэтому его изучение крайне важно для любого разработчика.
73 |
74 | В следующих разделах мы разберём, как JavaScript работает с асинхронным кодом с помощью **Promise**, **async/await** и других инструментов.
75 |
76 | ---
--------------------------------------------------------------------------------
/09.Итераторы и генераторы/0.Введение в итератор и генератор.md:
--------------------------------------------------------------------------------
1 | # 📌 Что такое итераторы и генераторы?
2 |
3 | **Итераторы** и **генераторы** — это инструменты в JavaScript, которые позволяют удобно и гибко перебирать значения по очереди. Вместо того чтобы сразу обрабатывать всю коллекцию (например, массив), вы можете обрабатывать элементы по одному — вручную или через цикл `for...of`.
4 |
5 | ---
6 |
7 | ## ❓ Зачем нужны итераторы?
8 |
9 | Итераторы позволяют:
10 |
11 | 1. **Обрабатывать данные поэтапно** — удобно для работы с большими или «бесконечными» наборами данных.
12 | 2. **Упростить перебор** любых итерируемых структур: массивов, строк, Set, Map и т. д.
13 | 3. **Создавать свои коллекции**, которые ведут себя как массивы.
14 | 4. **Инкапсулировать логику перебора** — то есть управлять тем, как и в каком порядке возвращаются значения.
15 |
16 | ---
17 |
18 | ## ❓ Как работает итератор?
19 |
20 | Итератор — это объект с методом `next()`, который возвращает объект следующего вида:
21 |
22 | ```
23 | { value: ..., done: ... }
24 | ```
25 |
26 | * `value` — значение текущего элемента.
27 | * `done` — булево значение: `true`, если перебор закончен.
28 |
29 | #### Пример:
30 |
31 | ```javascript
32 | const iterator = [10, 20, 30][Symbol.iterator]();
33 |
34 | console.log(iterator.next()); // { value: 10, done: false }
35 | console.log(iterator.next()); // { value: 20, done: false }
36 | console.log(iterator.next()); // { value: 30, done: false }
37 | console.log(iterator.next()); // { value: undefined, done: true }
38 | ```
39 |
40 | ---
41 |
42 | ## ❓Что такое генераторы?
43 |
44 | **Генераторы** — это особый тип функций, которые автоматически создают итераторы. Они объявляются через `function*` и используют ключевое слово `yield` для «приостановки» выполнения и возврата значений по очереди.
45 |
46 | #### Пример генератора:
47 |
48 | ```javascript
49 | function* numberGenerator() {
50 | yield 1;
51 | yield 2;
52 | yield 3;
53 | }
54 |
55 | const gen = numberGenerator();
56 | console.log(gen.next()); // { value: 1, done: false }
57 | console.log(gen.next()); // { value: 2, done: false }
58 | ```
59 |
60 | ---
61 |
62 | ## ❓ Где применяются итераторы и генераторы?
63 |
64 | * **Работа с коллекциями данных** — альтернатива циклам `for` и `while`
65 | * **Создание своих структур данных** — которые ведут себя как массивы или строки
66 | * **Ленивые вычисления** — когда значения нужны не сразу, а «по требованию»
67 | * **Асинхронная работа** (через `async generators`) — например, потоковая загрузка данных
68 |
69 | ---
70 |
71 | ## ❓ Как связаны с `for...of`?
72 |
73 | Если у объекта есть метод `Symbol.iterator`, он считается *итерируемым* и может использоваться в `for...of`:
74 |
75 | ```javascript
76 | const arr = [1, 2, 3];
77 | for (let item of arr) {
78 | console.log(item); // 1, 2, 3
79 | }
80 | ```
81 |
82 | `for...of` сам вызывает `next()` и обрабатывает результат — вам не нужно делать это вручную.
83 |
84 | ---
85 |
86 | ## 🎯 Итог
87 |
88 | Итераторы и генераторы делают JavaScript мощнее и гибче. Они позволяют по-новому взглянуть на перебор данных: пошагово, контролируемо, удобно. С их помощью можно создавать собственные коллекции, ленивые вычисления, асинхронные потоки и многое другое.
89 |
90 | ---
91 |
--------------------------------------------------------------------------------
/09.Итераторы и генераторы/3.Механизм итерации и работа генераторов.md:
--------------------------------------------------------------------------------
1 | # 📌 Механизм итерации и работа генераторов
2 |
3 | Итерация — это процесс последовательного получения значений из набора данных. В JavaScript за этим стоит специальный протокол, состоящий из **итерируемых объектов** и **итераторов**. Генераторы — это удобный инструмент для создания таких итераторов.
4 |
5 | ## Как работает механизм итерации?
6 |
7 | Итерация в JS основана на двух ключевых соглашениях:
8 |
9 | ### 🔹 1. **Итерируемые объекты**
10 | Любой объект, у которого есть метод `Symbol.iterator`, считается итерируемым. Этот метод должен возвращать **итератор**.
11 |
12 | ```javascript
13 | const iterable = {
14 | [Symbol.iterator]() {
15 | return {
16 | next() {
17 | return { value: 1, done: true };
18 | }
19 | };
20 | }
21 | };
22 | ````
23 |
24 | ### 🔹 2. **Итератор**
25 |
26 | Это объект с методом `next()`, который возвращает результат следующего шага итерации:
27 |
28 | ```
29 | { value: ..., done: ... }
30 | ```
31 |
32 | * `value` — следующее значение.
33 | * `done` — булевый флаг, указывающий, завершена ли итерация.
34 |
35 | ---
36 |
37 | ## Как используется в `for...of`
38 |
39 | Когда `for...of` запускается:
40 |
41 | 1. Проверяется наличие `Symbol.iterator`.
42 | 2. Вызывается метод `next()`, пока `done !== true`.
43 | 3. `value` передаётся в теле цикла.
44 |
45 | #### Пример:
46 |
47 | ```javascript
48 | const arr = [10, 20, 30];
49 |
50 | for (let val of arr) {
51 | console.log(val); // 10, 20, 30
52 | }
53 | ```
54 |
55 | ---
56 |
57 | ## Генераторы как итераторы
58 |
59 | **Генератор** — это функция, возвращающая итератор. Она пишется как `function*` и использует `yield`:
60 |
61 | ```javascript
62 | function* generateNumbers() {
63 | yield 1;
64 | yield 2;
65 | yield 3;
66 | }
67 | ```
68 |
69 | Такой генератор создаёт итератор, который запоминает своё состояние между вызовами `next()`:
70 |
71 | ```javascript
72 | const gen = generateNumbers();
73 |
74 | console.log(gen.next()); // { value: 1, done: false }
75 | console.log(gen.next()); // { value: 2, done: false }
76 | ```
77 |
78 | ---
79 |
80 | ## Преимущества генераторов
81 |
82 | * **Упрощение создания итераторов** — вся логика в одном месте.
83 | * **Пауза и возобновление выполнения** — через `yield`.
84 | * **Ленивая генерация данных** — экономия памяти.
85 | * **Асинхронные генераторы** (`async function*`) — удобно для потоков данных.
86 |
87 | ---
88 |
89 | ## Визуально: как работает итерация
90 |
91 | ```text
92 | [Symbol.iterator] → итератор → .next() → { value, done }
93 | ↓
94 | цикл for...of
95 | ```
96 |
97 | ---
98 |
99 | ## 🎯 Итог
100 |
101 | Механизм итерации делает JavaScript гибким и мощным. Он лежит в основе `for...of`, `spread`, `Array.from`, и многих других конструкций. Генераторы — это элегантный способ создавать собственные итераторы с минимальным кодом и максимальной читаемостью.
102 |
103 | ---
104 |
105 | ## 🏆 ЗАДАЧИ
106 |
107 | Вот задачи по **механизму итерации и генераторам**, не пересекающиеся с предыдущими. Каждая снабжена кодом, раскрытием вывода и пояснением решения:
108 |
109 | ---
110 |
111 | ### 📌 Задача 1: Перебор пользовательского объекта
112 |
113 | ❓ Что выведет следующий код?
114 |
115 | ```javascript
116 | const user = {
117 | name: "Alex",
118 | age: 30,
119 | [Symbol.iterator]() {
120 | let keys = Object.keys(this);
121 | let index = 0;
122 | return {
123 | next: () => {
124 | if (index < keys.length) {
125 | return { value: this[keys[index++]], done: false };
126 | } else {
127 | return { done: true };
128 | }
129 | }
130 | };
131 | }
132 | };
133 |
134 | for (let val of user) {
135 | console.log(val);
136 | }
137 | ```
138 |
139 |
140 | ✅ Вывод
141 |
142 | ```
143 | Alex
144 | 30
145 | ```
146 |
147 | **Объяснение**: `Symbol.iterator` создаёт итератор по значениям свойств. Он не обходит `Symbol.iterator` как ключ, так как `Object.keys()` его не включает.
148 |
149 |
150 |
151 | ---
152 |
153 | ### 📌 Задача 2: Вложенные генераторы
154 |
155 | ❓ Что выведет этот код?
156 |
157 | ```javascript
158 | function* inner() {
159 | yield 'a';
160 | yield 'b';
161 | }
162 |
163 | function* outer() {
164 | yield 'start';
165 | yield* inner();
166 | yield 'end';
167 | }
168 |
169 | for (let val of outer()) {
170 | console.log(val);
171 | }
172 | ```
173 |
174 |
175 | ✅ Вывод
176 |
177 | ```
178 | start
179 | a
180 | b
181 | end
182 | ```
183 |
184 | **Объяснение**: `yield* inner()` вставляет все значения из генератора `inner()` внутрь `outer()`. Это удобно для композиции итераций.
185 |
186 |
187 |
188 | ---
189 |
190 | ### 📌 Задача 3: Генератор с логикой
191 |
192 | ❓ Что выведет генератор?
193 |
194 | ```javascript
195 | function* countdown(from) {
196 | while (from > 0) {
197 | yield from--;
198 | }
199 | }
200 |
201 | for (let n of countdown(3)) {
202 | console.log(n);
203 | }
204 | ```
205 |
206 |
207 | ✅ Вывод
208 |
209 | ```
210 | 3
211 | 2
212 | 1
213 | ```
214 |
215 | **Объяснение**: Генератор использует `while` и `yield` для поэтапной генерации чисел от `from` до `1`. Поскольку `from--` постфиксный, сперва возвращается значение, потом уменьшается.
216 |
217 |
218 |
219 | ---
220 |
221 | ### 📌 Задача 4: Генератор + return
222 |
223 | ❓ Что будет выведено?
224 |
225 | ```javascript
226 | function* gen() {
227 | yield 1;
228 | return 2;
229 | yield 3;
230 | }
231 |
232 | const g = gen();
233 |
234 | console.log(g.next());
235 | console.log(g.next());
236 | console.log(g.next());
237 | ```
238 |
239 |
240 | ✅ Вывод
241 |
242 | ```
243 | { value: 1, done: false }
244 | { value: 2, done: true }
245 | { value: undefined, done: true }
246 | ```
247 |
248 | **Объяснение**: `return` завершает генератор и возвращает значение как `value`, при этом `done` становится `true`. Все `yield` после `return` игнорируются.
249 |
250 |
251 |
252 | ---
253 |
254 | 🎉 В данных задачах рассмотрены различные аспекты работы с генераторами и итераторами.
255 | Эти техники позволяют эффективно обрабатывать последовательности данных.
256 |
257 | ---
258 |
--------------------------------------------------------------------------------
/10.Базовые операторы/0.Введение в базовые операторы.md:
--------------------------------------------------------------------------------
1 | # 📌 Введение в базовые операторы JavaScript
2 |
3 | Когда вы начинаете изучать JavaScript, одним из первых и самых важных понятий, с которым стоит познакомиться, являются **операторы**. Это специальные символы или комбинации символов, которые позволяют выполнять действия над значениями: считать, сравнивать, принимать решения, присваивать и изменять данные.
4 |
5 | Операторы — это основа любой программы. Они встречаются практически в каждой строке кода и являются ключом к пониманию того, **как работают алгоритмы и логика** в JavaScript.
6 |
7 | ---
8 |
9 | ## ❓ Какие бывают базовые операторы?
10 |
11 | В JavaScript операторы делятся на несколько категорий:
12 |
13 | ### 🔹 Арифметические операторы
14 |
15 | Позволяют выполнять математические действия над числами.
16 |
17 | | Оператор | Описание | Пример | Результат |
18 | | -------- | ------------------------- | ------------------------------- | ---------------------- |
19 | | `+` | Сложение или конкатенация | `5 + 3` `'Hi ' + 'there!'` | `8` `'Hi there!'` |
20 | | `-` | Вычитание | `10 - 4` | `6` |
21 | | `*` | Умножение | `3 * 5` | `15` |
22 | | `/` | Деление | `10 / 2` | `5` |
23 | | `%` | Остаток от деления | `7 % 3` | `1` |
24 | | `**` | Возведение в степень | `2 ** 3` | `8` |
25 |
26 | ---
27 |
28 | ### 🔹 Операторы сравнения
29 |
30 | Используются для сравнения двух значений. Возвращают `true` или `false`.
31 |
32 | * `==` — Равно (с приведением типов)
33 |
34 | ```javascript
35 | 5 == '5'; // true
36 | ```
37 | * `===` — Строгое равенство (без приведения типов)
38 |
39 | ```javascript
40 | 5 === '5'; // false
41 | ```
42 | * `!=` — Не равно (с приведением типов)
43 |
44 | ```javascript
45 | 3 != '3'; // false
46 | ```
47 | * `!==` — Строгое неравенство
48 |
49 | ```javascript
50 | 3 !== '3'; // true
51 | ```
52 | * `>` — Больше
53 | * `<` — Меньше
54 | * `>=` — Больше или равно
55 | * `<=` — Меньше или равно
56 |
57 | ```javascript
58 | 10 > 5; // true
59 | 7 <= 7; // true
60 | ```
61 |
62 | ---
63 |
64 | ### 🔹 Логические операторы
65 |
66 | Применяются для логических выражений.
67 |
68 | * `&&` — И (оба условия должны быть истинны)
69 |
70 | ```javascript
71 | true && false; // false
72 | ```
73 | * `||` — ИЛИ (достаточно одного истинного)
74 |
75 | ```javascript
76 | true || false; // true
77 | ```
78 | * `!` — НЕ (инвертирует значение)
79 |
80 | ```javascript
81 | !true; // false
82 | ```
83 |
84 | ---
85 |
86 | ### 🔹 Операторы присваивания
87 |
88 | Используются для присвоения или изменения значений переменных.
89 |
90 | * `=` — простое присваивание
91 |
92 | ```javascript
93 | let x = 10;
94 | ```
95 | * `+=`, `-=`, `*=`, `/=`, `%=` — сокращённые формы записи
96 |
97 | ```javascript
98 | let y = 5;
99 | y += 3; // y = 8
100 | ```
101 |
102 | ---
103 |
104 | ### 🔹 Унарные операторы (инкремент и декремент)
105 |
106 | Работают с одной переменной.
107 |
108 | * `++` — увеличивает на 1
109 | * `--` — уменьшает на 1
110 |
111 | ```javascript
112 | let count = 0;
113 | count++; // 1
114 | count--; // 0
115 | ```
116 |
117 | ---
118 |
119 | ### 🔹 Тернарный оператор
120 |
121 | Позволяет писать короткие условия.
122 |
123 | ```javascript
124 | let age = 20;
125 | let message = age >= 18 ? 'Совершеннолетний' : 'Несовершеннолетний';
126 | // message = 'Совершеннолетний'
127 | ```
128 |
129 | ---
130 |
131 | ### 🔹 Оператор запятая
132 |
133 | Позволяет выполнить несколько выражений, возвращая **результат последнего**:
134 |
135 | ```javascript
136 | let result = (1 + 2, 3 + 4); // result = 7
137 | ```
138 |
139 | ---
140 |
141 | ## 🎯 Итог
142 |
143 | Операторы — это фундамент любого кода на JavaScript. Без них не получится реализовать ни вычислений, ни условий, ни взаимодействия с переменными. Понимание того, **как и когда использовать каждый тип оператора**, — это первый шаг на пути к написанию грамотных, читаемых и логичных программ.
144 |
145 | ---
146 |
--------------------------------------------------------------------------------
/10.Базовые операторы/2.Операторы присваивания.md:
--------------------------------------------------------------------------------
1 | # 📌 Операторы присваивания
2 |
3 | Операторы присваивания позволяют **устанавливать или изменять значения переменных**. Они часто используются в сочетании с арифметическими операциями, чтобы сделать код короче и понятнее.
4 |
5 | ---
6 |
7 | ### Простое присваивание (`=`)
8 |
9 | Это базовый оператор, с которого начинается любое присваивание:
10 |
11 | ```javascript
12 | let a = 10;
13 | ```
14 |
15 | Он просто сохраняет значение `10` в переменную `a`.
16 |
17 | ---
18 |
19 | ### Составные операторы присваивания
20 |
21 | Эти операторы **выполняют математическое действие и сразу сохраняют результат в той же переменной**. Они сокращают запись выражений и часто используются в циклах, накоплении значений и изменении состояния.
22 |
23 | #### 🔹 1. `+=` — прибавление и присваивание
24 |
25 | ```javascript
26 | let a = 5;
27 | a += 3; // то же самое, что a = a + 3
28 | console.log(a); // 8
29 | ```
30 |
31 | #### 🔹 2. `-=` — вычитание и присваивание
32 |
33 | ```javascript
34 | let a = 10;
35 | a -= 4; // то же самое, что a = a - 4
36 | console.log(a); // 6
37 | ```
38 |
39 | #### 🔹 3. `*=` — умножение и присваивание
40 |
41 | ```javascript
42 | let a = 4;
43 | a *= 2; // эквивалентно a = a * 2
44 | console.log(a); // 8
45 | ```
46 |
47 | #### 🔹 4. `/=` — деление и присваивание
48 |
49 | ```javascript
50 | let a = 20;
51 | a /= 4; // a = a / 4
52 | console.log(a); // 5
53 | ```
54 |
55 | #### 🔹 5. `%=` — остаток от деления и присваивание
56 |
57 | ```javascript
58 | let a = 7;
59 | a %= 3; // a = a % 3
60 | console.log(a); // 1
61 | ```
62 |
63 | #### 🔹 6. `**=` — возведение в степень и присваивание
64 |
65 | ```javascript
66 | let a = 2;
67 | a **= 3; // a = a ** 3
68 | console.log(a); // 8
69 | ```
70 |
71 | ---
72 |
73 | ### Разница между `+=` и `-=`:
74 |
75 | | Оператор | Что делает | Пример | Результат |
76 | | -------- | ------------------- | -------- | ----------- |
77 | | `+=` | Прибавляет значение | `a += 5` | `a = a + 5` |
78 | | `-=` | Вычитает значение | `a -= 3` | `a = a - 3` |
79 |
80 | Оба оператора изменяют значение переменной, но выполняют **противоположные действия** — один увеличивает, другой уменьшает.
81 |
82 | ---
83 |
84 | ## 🎯 Итог
85 |
86 | Операторы присваивания — это не просто способ "присвоить" значение. Они позволяют **изменять переменную в контексте операций**: сложения, вычитания, умножения и т.д.
87 |
88 | * Использование составных операторов (`+=`, `-=`, `*=` и др.) **делает код короче, читабельнее и выразительнее**.
89 | * Такие операторы особенно полезны в **циклах, подсчётах, обработке данных и управлении состоянием переменных**.
90 |
91 | ---
92 |
93 | ## 🏆 ЗАДАЧИ
94 |
95 | Задачи по теме `Операторы присваивания`
96 |
97 | ---
98 |
99 | Отлично! Давайте добавим **практические задачи по операторам присваивания** в том же формате, что и раньше — с описанием, кодом, и выводом в спойлере.
100 |
101 | ---
102 |
103 | ### 📌 Задача 1: Использование `+=` и `-=`
104 |
105 | Измените значение переменной с помощью операторов `+=` и `-=`.
106 |
107 | ```javascript
108 | let score = 10;
109 |
110 | score += 15;
111 | score -= 5;
112 |
113 | console.log(score); // ?
114 | ```
115 |
116 |
117 | ✍ Решение
118 |
119 | ```javascript
120 | score = 10 + 15 = 25
121 | score = 25 - 5 = 20
122 | console.log(score); // 20
123 | ```
124 |
125 |
126 |
127 | ---
128 |
129 | ### 📌 Задача 2: Умножение и деление
130 |
131 | Преобразуйте значение переменной, используя `*=` и `/=`.
132 |
133 | ```javascript
134 | let value = 8;
135 |
136 | value *= 2;
137 | value /= 4;
138 |
139 | console.log(value); // ?
140 | ```
141 |
142 |
143 | ✍ Решение
144 |
145 | ```javascript
146 | value = 8 * 2 = 16
147 | value = 16 / 4 = 4
148 | console.log(value); // 4
149 | ```
150 |
151 |
152 |
153 | ---
154 |
155 | ### 📌 Задача 3: Остаток и степень
156 |
157 | Примените `%=` и `**=` для получения остатка и возведения в степень.
158 |
159 | ```javascript
160 | let num = 10;
161 |
162 | num %= 4;
163 | num **= 2;
164 |
165 | console.log(num); // ?
166 | ```
167 |
168 |
169 | ✍ Решение
170 |
171 | ```javascript
172 | num = 10 % 4 = 2
173 | num = 2 ** 2 = 4
174 | console.log(num); // 4
175 | ```
176 |
177 |
178 |
179 | ---
180 |
181 | ### 📌 Задача 4: Последовательные операции
182 |
183 | Выполните несколько операций с одной переменной.
184 |
185 | ```javascript
186 | let total = 2;
187 |
188 | total += 3;
189 | total *= 4;
190 | total -= 5;
191 |
192 | console.log(total); // ?
193 | ```
194 |
195 |
196 | ✍ Решение
197 |
198 | ```javascript
199 | total = 2 + 3 = 5
200 | total = 5 * 4 = 20
201 | total = 20 - 5 = 15
202 | console.log(total); // 15
203 | ```
204 |
205 |
206 |
207 | ---
208 |
209 | 🎉 Эти задачи помогут вам закрепить знание операторов присваивания в JavaScript:
210 |
211 | * Вы научитесь быстро и эффективно изменять значения переменных.
212 | * Поймёте, как упрощать код с помощью `+=`, `-=`, `*=`, `/=`, `%=` и `**=`.
213 | * Приобретёте практику, полезную в реальных задачах: подсчёты, циклы, обработка числовых данных.
214 |
215 | ---
216 |
--------------------------------------------------------------------------------
/10.Базовые операторы/3.Операторы инкремент и декремент.md:
--------------------------------------------------------------------------------
1 | # 📌 Разница между `++i` и `i++` в JavaScript
2 |
3 | В JavaScript оператор `++` используется для **увеличения значения переменной на 1**. Но то, **где он размещается** — перед переменной (`++i`) или после (`i++`), — **влияет на порядок выполнения** и возвращаемое значение.
4 |
5 | ---
6 |
7 | ### 🔹 `++i` — префиксный инкремент
8 |
9 | * **Что делает:** Увеличивает значение переменной на 1 **и сразу возвращает новое значение**.
10 | * **Когда используется:** Если вам нужно, чтобы переменная изменилась **до** того, как она попадет в выражение.
11 |
12 | #### Пример:
13 |
14 | ```javascript
15 | let i = 5;
16 | let result = ++i; // i сначала увеличивается до 6, затем это значение присваивается result
17 |
18 | console.log(result); // 6
19 | console.log(i); // 6
20 | ```
21 |
22 | ---
23 |
24 | ### 🔹 `i++` — постфиксный инкремент
25 |
26 | * **Что делает:** Сначала возвращает **текущее значение переменной**, а затем увеличивает её на 1.
27 | * **Когда используется:** Если нужно сначала использовать **старое значение**, а потом обновить переменную.
28 |
29 | #### Пример:
30 |
31 | ```javascript
32 | let i = 5;
33 | let result = i++; // сначала значение i (5) присваивается result, потом i становится 6
34 |
35 | console.log(result); // 5
36 | console.log(i); // 6
37 | ```
38 |
39 | ---
40 |
41 | ### 🔹 Сравнение поведения
42 |
43 | | Оператор | Когда увеличивает значение | Что возвращает |
44 | | -------- | -------------------------- | --------------- |
45 | | `++i` | До использования | Новое значение |
46 | | `i++` | После использования | Старое значение |
47 |
48 | ---
49 |
50 | ### 🔹 Использование в выражениях
51 |
52 | Обе формы особенно важны в **сложных выражениях**, циклах, или функциях, где важно **порядок действий**.
53 |
54 | ```javascript
55 | let i = 3;
56 | console.log(++i + 2); // 4 + 2 = 6
57 |
58 | i = 3;
59 | console.log(i++ + 2); // 3 + 2 = 5 (но i после этого = 4)
60 | ```
61 |
62 | ---
63 |
64 | ## 🎯 Итог
65 |
66 | * Оператор `++` увеличивает значение переменной на 1.
67 | * Разница между `++i` и `i++` заключается в **моменте, когда происходит увеличение значения**:
68 |
69 | * `++i`: сначала увеличивает, потом возвращает.
70 | * `i++`: сначала возвращает, потом увеличивает.
71 |
72 | Понимание этой разницы особенно важно при использовании инкремента в условиях, выражениях и циклах (`for`, `while`). Это помогает избежать ошибок в логике и получить предсказуемый результат.
73 |
74 | ## 🏆 ЗАДАЧИ
75 |
76 | Задачи по теме `Оператор инкримент и декримент`
77 |
78 | ---
79 |
80 |
81 | ### 📌 Задача 1: Префиксный инкремент
82 |
83 | Проверь, как изменяется переменная при использовании `++i`.
84 |
85 | ```javascript
86 | let i = 2;
87 | let result = ++i;
88 |
89 | console.log(result); // ?
90 | console.log(i); // ?
91 | ```
92 |
93 |
94 | ✅ Вывод
95 |
96 | ```javascript
97 | // i сначала увеличивается до 3
98 | // result получает новое значение — 3
99 | console.log(result); // 3
100 | console.log(i); // 3
101 | ```
102 |
103 |
104 |
105 | ---
106 |
107 | ### 📌 Задача 2: Постфиксный инкремент
108 |
109 | Сравни поведение с `i++`.
110 |
111 | ```javascript
112 | let i = 2;
113 | let result = i++;
114 |
115 | console.log(result); // ?
116 | console.log(i); // ?
117 | ```
118 |
119 |
120 | ✅ Вывод
121 |
122 | ```javascript
123 | // result сначала получает текущее значение i — 2
124 | // потом i увеличивается до 3
125 | console.log(result); // 2
126 | console.log(i); // 3
127 | ```
128 |
129 |
130 |
131 | ---
132 |
133 | ### 📌 Задача 3: Инкремент в выражении
134 |
135 | Убедись, как префикс и постфикс влияют на результат арифметического выражения.
136 |
137 | ```javascript
138 | let i = 3;
139 |
140 | let a = ++i + 1; // ?
141 | let b = i++ + 1; // ?
142 |
143 | console.log(a); // ?
144 | console.log(b); // ?
145 | console.log(i); // ?
146 | ```
147 |
148 |
149 | ✅ Вывод
150 |
151 | ```javascript
152 | // ++i → i становится 4, a = 4 + 1 = 5
153 | // i++ → b = 4 + 1 = 5, потом i становится 5
154 | console.log(a); // 5
155 | console.log(b); // 5
156 | console.log(i); // 5
157 | ```
158 |
159 |
160 |
161 | ---
162 |
163 | ### 📌 Задача 4: Использование в цикле
164 |
165 | Посмотри, как `++i` и `i++` работают внутри цикла.
166 |
167 | ```javascript
168 | for (let i = 0; i < 3; ) {
169 | console.log(i++); // ?
170 | }
171 | ```
172 |
173 |
174 | ✅ Вывод
175 |
176 | ```javascript
177 | // i выводится, затем увеличивается
178 | // Вывод: 0, 1, 2
179 | ```
180 |
181 |
182 |
183 | ---
184 |
185 | ### 📌 Задача 5: Сравнение с нулем
186 |
187 | Проанализируй порядок изменений переменной.
188 |
189 | ```javascript
190 | let x = 0;
191 |
192 | if (x++ === 0) {
193 | console.log("x было 0");
194 | }
195 |
196 | console.log(x); // ?
197 | ```
198 |
199 |
200 | ✅ Вывод
201 |
202 | ```javascript
203 | // x++ сначала сравнивает 0 === 0 → true
204 | // потом x становится 1
205 | console.log("x было 0");
206 | console.log(x); // 1
207 | ```
208 |
209 |
210 |
211 | ---
212 |
213 | 🎉 Эти задачи помогают закрепить:
214 |
215 | * разницу между `++i` и `i++`;
216 | * то, как инкремент влияет на результат выражений;
217 | * понимание порядка выполнения операций в коде.
218 |
219 | ---
220 |
--------------------------------------------------------------------------------
/10.Базовые операторы/4.Операторы (&&) и (||).md:
--------------------------------------------------------------------------------
1 | # 📌 Логические операторы `&&` и `||` в JavaScript
2 |
3 | Логические операторы в JavaScript управляют выполнением выражений на основе истинности значений. Два самых часто используемых логических оператора:
4 |
5 | * `&&` (логическое И)
6 | * `||` (логическое ИЛИ)
7 |
8 | Они не только возвращают булевы значения, но и участвуют в **логическом сокращении (short-circuit evaluation)**, а также могут возвращать **любое значение** — не обязательно `true` или `false`.
9 |
10 | ---
11 |
12 | ### 🔹 `&&` — Логическое И
13 |
14 | **Синтаксис:**
15 |
16 | ```javascript
17 | a && b
18 | ```
19 |
20 | **Поведение:**
21 |
22 | * Если **первое значение ложно**, оно сразу возвращается.
23 | * Если **первое значение истинно**, возвращается **второе значение**.
24 | * Используется для выполнения кода **только если оба условия истинны**.
25 |
26 | **Примеры:**
27 |
28 | ```javascript
29 | true && true // true
30 | true && false // false
31 | false && true // false
32 | false && false // false
33 | ```
34 |
35 | **С не булевыми значениями:**
36 |
37 | ```javascript
38 | 'hello' && 42 // 42 (оба значения истинны)
39 | 0 && 'text' // 0 (первое — ложное)
40 | null && 'value' // null (short-circuit)
41 | true && undefined // undefined
42 | ```
43 |
44 | **Полезный паттерн:**
45 |
46 | ```javascript
47 | user && user.name // Проверяет, существует ли объект user, прежде чем обратиться к user.name
48 | ```
49 |
50 | ---
51 |
52 | ### 🔹 `||` — Логическое ИЛИ
53 |
54 | **Синтаксис:**
55 |
56 | ```javascript
57 | a || b
58 | ```
59 |
60 | **Поведение:**
61 |
62 | * Если **первое значение истинно**, оно возвращается.
63 | * Если **первое значение ложно**, возвращается **второе значение**.
64 | * Используется для задания **значения по умолчанию** или проверки, что **хотя бы одно условие выполнено**.
65 |
66 | **Примеры:**
67 |
68 | ```javascript
69 | true || false // true
70 | false || true // true
71 | false || false // false
72 | ```
73 |
74 | **С не булевыми значениями:**
75 |
76 | ```javascript
77 | 0 || 'default' // 'default' (0 — ложь)
78 | '' || 'fallback' // 'fallback'
79 | null || undefined // undefined
80 | 'text' || 123 // 'text' (первое истинное значение)
81 | ```
82 |
83 | **Полезный паттерн:**
84 |
85 | ```javascript
86 | let name = input || 'Guest'; // Если input — falsy, использовать 'Guest'
87 | ```
88 |
89 | ---
90 |
91 | ### 🔹 Поведение при короткой оценке (short-circuit evaluation)
92 |
93 | * `&&` останавливается на **первом ложном** значении.
94 | * `||` останавливается на **первом истинном** значении.
95 |
96 | Это важно при вызове функций или вычислении выражений:
97 |
98 | ```javascript
99 | isLoggedIn && showDashboard(); // вызовется только если isLoggedIn == true
100 | errorMessage || 'Все хорошо'; // вернет сообщение или текст по умолчанию
101 | ```
102 |
103 | ---
104 |
105 | ## 🎯 Итог
106 |
107 | | Оператор | Условие | Возвращает | | |
108 | | -------- | -------------------- | ------------------------------------ | -------------------- | ------------------------------------ |
109 | | `&&` | Оба значения истинны | Первое ложное или последнее истинное | | |
110 | | \` | | \` | Хотя бы одно истинно | Первое истинное или последнее ложное |
111 |
112 | * Оба оператора возвращают **первое значение, необходимое для определения результата**, а не просто `true`/`false`.
113 | * Широко применяются для проверки условий, присваивания значений по умолчанию и управления выполнением кода.
114 |
115 | ## 🏆 ЗАДАЧИ
116 |
117 | Вот подборка практических задач, которые помогут закрепить понимание работы логических операторов `&&` и `||` в JavaScript.
118 |
119 | ---
120 |
121 | ### 📌 Задача 1: Проверка на существование
122 |
123 | Убедитесь, что переменная `user` существует, прежде чем вывести имя пользователя.
124 |
125 | ```javascript
126 | let user = { name: "Anna" };
127 |
128 | console.log(user && user.name); // ?
129 | ```
130 |
131 |
132 | ✅ Вывод
133 |
134 | ```javascript
135 | "Anna" — оператор && проверяет, что user существует, и возвращает user.name.
136 | ```
137 |
138 |
139 |
140 | ---
141 |
142 | ### 📌 Задача 2: Значение по умолчанию
143 |
144 | Если значение переменной `input` ложно, установите `"Значение по умолчанию"`.
145 |
146 | ```javascript
147 | let input = "";
148 |
149 | let result = input || "Значение по умолчанию";
150 | console.log(result); // ?
151 | ```
152 |
153 |
154 | ✅ Вывод
155 |
156 | ```javascript
157 | "Значение по умолчанию" — пустая строка `""` считается ложным значением.
158 | ```
159 |
160 |
161 |
162 | ---
163 |
164 | ### 📌 Задача 3: Комбинированные операторы
165 |
166 | ❓ Что выведется в консоль?
167 |
168 | ```javascript
169 | let a = 0;
170 | let b = "text";
171 | let c = null;
172 |
173 | console.log(a || b && c); // ?
174 | ```
175 |
176 |
177 | ✍ Объяснение
178 |
179 | * `b && c` → `"text" && null` → `null`
180 | * `a || null` → `0 || null` → `null`
181 |
182 |
183 |
184 | ---
185 |
186 | ### 📌 Задача 4: Условный вызов функции
187 |
188 | ❓ Вызовите функцию только если пользователь авторизован.
189 |
190 | ```javascript
191 | let isLoggedIn = true;
192 |
193 | function showDashboard() {
194 | console.log("Добро пожаловать!");
195 | }
196 |
197 | isLoggedIn && showDashboard(); // ?
198 | ```
199 |
200 |
201 | ✅ Вывод
202 |
203 | ```javascript
204 | "Добро пожаловать!" — функция вызывается, потому что isLoggedIn === true
205 | ```
206 |
207 |
208 |
209 | ---
210 |
211 | ### 📌 Задача 5: Последовательность значений
212 |
213 | ❓ Что вернет результат?
214 |
215 | ```javascript
216 | console.log(null || 0 || "" || undefined || "Привет" || 42); // ?
217 | ```
218 |
219 |
220 | ✅ Вывод
221 |
222 | ```javascript
223 | "Привет" — это первое истинное значение в цепочке ||.
224 | ```
225 |
226 |
227 |
228 | ---
229 |
230 | 🎉 Эти задачи помогут вам лучше понять поведение операторов `&&` и `||`, их приоритет и применение для обработки условий, значений по умолчанию и безопасного доступа к данным.
231 |
232 | ---
233 |
--------------------------------------------------------------------------------
/10.Базовые операторы/5.Операторы (??) и (?.).md:
--------------------------------------------------------------------------------
1 | # 📌 Операторы ?? и ?.
2 |
3 | Два современных и очень удобных оператора JavaScript — **nullish coalescing (`??`)** и **optional chaining (`?.`)**. Оба оператора значительно упрощают работу с переменными и объектами, особенно когда есть вероятность, что данные могут быть `null` или `undefined`.
4 |
5 | ---
6 |
7 | ## 🔹 Nullish coalescing (`??`)
8 |
9 | ### Что делает?
10 |
11 | Оператор **nullish coalescing** возвращает **первый операнд**, если он **не является `null` или `undefined`**, и **второй** в противном случае.
12 |
13 | Он похож на логический оператор `||`, но с важным отличием: `??` **не считает ложными значениями** такие как `0`, `false`, `""` (пустая строка). Он проверяет только `null` и `undefined`.
14 |
15 | ### Синтаксис:
16 |
17 | ```javascript
18 | let result = a ?? b;
19 | ```
20 |
21 | * Возвращает `a`, если `a !== null && a !== undefined`.
22 | * Иначе возвращает `b`.
23 |
24 | ### Примеры:
25 |
26 | ```javascript
27 | let name = null;
28 | let defaultName = "Гость";
29 |
30 | let finalName = name ?? defaultName;
31 | console.log(finalName); // "Гость"
32 | ```
33 |
34 | ```javascript
35 | let count = 0;
36 | let result = count ?? 10;
37 | console.log(result); // 0 — потому что 0 не является ни null, ни undefined
38 | ```
39 |
40 | Это поведение делает `??` особенно полезным, если вы хотите задать значение **по умолчанию**, но при этом **не перезаписывать допустимые значения** вроде `0`, `false` или `""`.
41 |
42 | ---
43 |
44 | ## 🔹 Optional chaining (`?.`)
45 |
46 | ### Что делает?
47 |
48 | Оператор **optional chaining (`?.`)** позволяет **безопасно обращаться к вложенным свойствам объекта**, которые могут быть `null` или `undefined`.
49 |
50 | Он **предотвращает ошибку**, которая возникает при попытке получить доступ к свойству у `undefined` или `null`.
51 |
52 | ### Синтаксис:
53 |
54 | ```javascript
55 | let result = obj?.prop;
56 | ```
57 |
58 | * Возвращает `undefined`, если `obj` — `null` или `undefined`.
59 | * Иначе возвращает `obj.prop`.
60 |
61 | Можно использовать для:
62 |
63 | * Доступа к свойствам: `obj?.property`
64 | * Вызова методов: `obj?.method()`
65 | * Доступа к элементам массива: `arr?.[index]`
66 |
67 | ### Примеры:
68 |
69 | ```javascript
70 | let user = {
71 | name: "Иван",
72 | address: {
73 | city: "Москва"
74 | }
75 | };
76 |
77 | console.log(user.address?.city); // "Москва"
78 | console.log(user.contact?.email); // undefined (без ошибки)
79 | ```
80 |
81 | ```javascript
82 | let users = null;
83 | console.log(users?.[0]); // undefined
84 | ```
85 |
86 | ```javascript
87 | let obj = null;
88 | obj?.method(); // ничего не произойдёт, ошибки не будет
89 | ```
90 |
91 | ### Зачем нужен?
92 |
93 | Optional chaining особенно полезен, когда:
94 |
95 | * Вы не уверены, существует ли объект или его вложенное свойство.
96 | * Нужно избежать лишних проверок `if (obj && obj.prop && obj.prop.inner)...`
97 | * Требуется краткая и безопасная запись.
98 |
99 | ---
100 |
101 | ## 🎯 Итог
102 |
103 | | Оператор | Назначение | Пример |
104 | | -------- | ----------------------------------------------------------------- | ---------------------------- |
105 | | `??` | Возвращает первый "не null/undefined" операнд | `value = input ?? "default"` |
106 | | `?.` | Безопасно обращается к свойству или методу, если объект не `null` | `user?.info?.email` |
107 |
108 | Оба оператора появились в ES2020 и делают код более **читаемым**, **коротким** и **безопасным** при работе с необязательными или частично заполненными данными.
109 |
110 | ## 🏆 ЗАДАЧИ
111 | Вот подборка задач, чтобы на практике закрепить работу операторов **nullish coalescing (`??`)** и **optional chaining (`?.`)** в JavaScript.
112 |
113 | ---
114 |
115 | ### 📌 Задача 1: Значение по умолчанию
116 |
117 | ❓ Что выведет следующий код?
118 |
119 | ```javascript
120 | let input = "";
121 | let result = input ?? "По умолчанию";
122 | console.log(result); // ?
123 | ```
124 |
125 |
126 | ✅ Вывод
127 |
128 | ```javascript
129 | "" — потому что `??` не считает пустую строку ложным значением. Только `null` и `undefined`.
130 | ```
131 |
132 |
133 |
134 | ---
135 |
136 | ### 📌 Задача 2: Сравнение с ||
137 |
138 | ❓ В чём разница в выводе между `||` и `??`?
139 |
140 | ```javascript
141 | let count = 0;
142 |
143 | console.log(count || 10); // ?
144 | console.log(count ?? 10); // ?
145 | ```
146 |
147 |
148 | ✅ Вывод
149 |
150 | ```javascript
151 | console.log(count || 10); // 10 — потому что 0 считается ложным значением
152 | console.log(count ?? 10); // 0 — потому что 0 !== null и !== undefined
153 | ```
154 |
155 |
156 |
157 | ---
158 |
159 | ### 📌 Задача 3: Безопасный доступ
160 |
161 | ❓ Как безопасно обратиться к адресу пользователя?
162 |
163 | ```javascript
164 | let user = {
165 | name: "Анна",
166 | // address отсутствует
167 | };
168 |
169 | console.log(user.address?.city); // ?
170 | ```
171 |
172 |
173 | ✅ Вывод
174 |
175 | ```javascript
176 | undefined — `user.address` не существует, но благодаря `?.` ошибки не будет.
177 | ```
178 |
179 |
180 |
181 | ---
182 |
183 | ### 📌 Задача 4: Безопасный вызов метода
184 |
185 | ❓ Что произойдёт при попытке вызвать метод?
186 |
187 | ```javascript
188 | let user = {
189 | name: "Марк"
190 | };
191 |
192 | user.sayHi?.(); // ?
193 | ```
194 |
195 |
196 | ✅ Вывод
197 |
198 | ```javascript
199 | Ничего — метод sayHi не существует, `?.()` предотвратит ошибку вызова.
200 | ```
201 |
202 |
203 |
204 | ---
205 |
206 | ### 📌 Задача 5: Проверка элемента массива
207 |
208 | ❓ Как получить первый элемент массива, если сам массив может быть `null`?
209 |
210 | ```javascript
211 | let users = null;
212 |
213 | console.log(users?.[0]); // ?
214 | ```
215 |
216 |
217 | ✅ Вывод
218 |
219 | ```javascript
220 | undefined — доступ к первому элементу безопасно возвращает undefined без ошибки.
221 | ```
222 |
223 |
224 |
225 | ---
226 |
227 | 🎉 Эти задачи помогут вам уверенно применять `??` и `?.` в повседневной разработке: при обработке необязательных данных, значений по умолчанию, вызове функций и работе с вложенными структурами.
228 |
229 | ---
230 |
--------------------------------------------------------------------------------
/10.Базовые операторы/6.Тернарный оператор.md:
--------------------------------------------------------------------------------
1 | # 📌 Тернарный оператор в JavaScript
2 |
3 | Тернарный оператор в JavaScript — это короткая форма записи условного выражения `if...else`. Он позволяет выполнить одно из двух выражений в зависимости от истинности условия.
4 |
5 | Полное название: **тернарный условный оператор**, так как он работает с тремя операндами:
6 | `условие ? выражение1 : выражение2`
7 |
8 | ---
9 |
10 | ### 🔹 Синтаксис
11 |
12 | ```javascript
13 | условие ? выражениеЕслиИстина : выражениеЕслиЛожь
14 | ```
15 |
16 | * Если **условие** истинно (truthy), выполняется и возвращается `выражениеЕслиИстина`.
17 | * Если **условие** ложно (falsy), выполняется и возвращается `выражениеЕслиЛожь`.
18 |
19 | ---
20 |
21 | ### 🔹 Пример
22 |
23 | ```javascript
24 | let age = 20;
25 | let access = (age >= 18) ? "Доступ разрешён" : "Доступ запрещён";
26 | console.log(access); // "Доступ разрешён"
27 | ```
28 |
29 | Здесь вместо длинной конструкции `if...else`, мы получили результат с помощью тернарного оператора.
30 |
31 | ---
32 |
33 | ### 🔹 Особенности
34 |
35 | * Тернарный оператор можно **вложить**, но злоупотреблять этим не стоит, т.к. это ухудшает читаемость кода.
36 |
37 | ```javascript
38 | let score = 85;
39 | let grade = score >= 90 ? "A" :
40 | score >= 80 ? "B" :
41 | score >= 70 ? "C" : "F";
42 | console.log(grade); // "B"
43 | ```
44 |
45 | * Часто используется для установки значений по условию в одну строку, особенно в JSX (React) или внутри шаблонов.
46 |
47 | ---
48 |
49 | ### 🔹 Когда использовать?
50 |
51 | * Когда нужно **присвоить значение** на основе условия.
52 | * Когда условие **простое и читаемое**.
53 | * Когда нужно **сократить запись**, например, в однострочниках, возврате из функции и т.п.
54 |
55 | ---
56 |
57 | ## 🎯 Итог
58 |
59 | Тернарный оператор не заменяет `if...else` во всех случаях. Если логика сложная, содержит несколько операторов или побочные эффекты (например, изменение состояния), предпочтительнее использовать обычный `if`.
60 |
61 | ## 🏆 ЗАДАЧИ
62 |
63 | Вот задачи, которые помогут закрепить знание **тернарного оператора (`? :`)** в JavaScript.
64 |
65 | ---
66 |
67 | ### 📌 Задача 1: Проверка возраста
68 |
69 | ❓ Используя тернарный оператор, выведите сообщение в зависимости от возраста:
70 |
71 | ```javascript
72 | let age = 16;
73 | let message = age >= 18 ? "Доступ разрешён" : "Доступ запрещён";
74 | console.log(message); // ?
75 | ```
76 |
77 |
78 | ✅ Вывод
79 |
80 | ```javascript
81 | "Доступ запрещён" — условие false (16 < 18), выбирается вторая ветка.
82 | ```
83 |
84 |
85 |
86 | ---
87 |
88 | ### 📌 Задача 2: Вложенные условия
89 |
90 | ❓ Что выведет данный код?
91 |
92 | ```javascript
93 | let score = 75;
94 | let grade = score >= 90 ? "A" :
95 | score >= 80 ? "B" :
96 | score >= 70 ? "C" : "F";
97 | console.log(grade); // ?
98 | ```
99 |
100 |
101 | ✅ Вывод
102 |
103 | ```javascript
104 | "C" — первое условие false (75 < 90), второе false, третье true.
105 | ```
106 |
107 |
108 |
109 | ---
110 |
111 | ### 📌 Задача 3: Сравнение с if
112 |
113 | ❓ Преобразуйте этот `if...else` в тернарный оператор:
114 |
115 | ```javascript
116 | let isOnline = true;
117 | let status;
118 |
119 | if (isOnline) {
120 | status = "Пользователь в сети";
121 | } else {
122 | status = "Пользователь не в сети";
123 | }
124 | ```
125 |
126 |
127 | ✍ Решение
128 |
129 | ```javascript
130 | let isOnline = true;
131 | let status = isOnline ? "Пользователь в сети" : "Пользователь не в сети";
132 | ```
133 |
134 |
135 |
136 | ---
137 |
138 | ### 📌 Задача 4: Проверка на пустую строку
139 |
140 | ❓ Что выведет этот код?
141 |
142 | ```javascript
143 | let name = "";
144 | let greeting = name ? "Привет, " + name : "Привет, гость!";
145 | console.log(greeting); // ?
146 | ```
147 |
148 |
149 | ✅ Вывод
150 |
151 | ```javascript
152 | "Привет, гость!" — пустая строка считается ложным значением.
153 | ```
154 |
155 |
156 |
157 | ---
158 |
159 | ### 📌 Задача 5: Тернарный в return
160 |
161 | ❓ Что вернёт функция?
162 |
163 | ```javascript
164 | function getAccess(role) {
165 | return role === "admin" ? "Полный доступ" : "Ограниченный доступ";
166 | }
167 |
168 | console.log(getAccess("user")); // ?
169 | ```
170 |
171 |
172 | ✅ Вывод
173 |
174 | ```javascript
175 | "Ограниченный доступ" — условие false.
176 | ```
177 |
178 |
179 |
180 | ---
181 |
182 | 🎉 Эти задачи помогут вам уверенно использовать тернарный оператор для краткой записи условий, настройки поведения функций и определения значений переменных.
183 |
184 | ---
185 |
186 |
--------------------------------------------------------------------------------
/10.Базовые операторы/7.Оператор (&).md:
--------------------------------------------------------------------------------
1 | # 📌 Что делает оператор `&` в JavaScript?
2 |
3 | Оператор `&` — **побитовый AND**. Он сравнивает **два числа побитово**, и в каждом бите возвращает `1`, только если **оба бита равны 1**. Во всех остальных случаях — `0`.
4 |
5 | #### Пример:
6 |
7 | ```javascript
8 | console.log(5 & 3); // 1
9 | ```
10 |
11 | #### Почему?
12 |
13 | * 5 в двоичной: `0101`
14 | * 3 в двоичной: `0011`
15 | * Результат: `0001` = `1`
16 |
17 | Этот оператор **не работает с логическими значениями**, как `&&`, он **работает с числами**, и его результат — **число**, а не булево значение.
18 |
19 | ---
20 |
21 | ## 🔹 Что означает `~array.indexOf(item)`?
22 |
23 | Это старая идиома, которую часто можно увидеть в старом JavaScript-коде. Давайте разберёмся:
24 |
25 | ### ❓ Как работает `indexOf()`?
26 |
27 | Метод `array.indexOf(item)` возвращает:
28 |
29 | * индекс элемента, если он найден (например, `0`, `1`, `5`, и т.д.),
30 | * `-1`, если элемент не найден.
31 |
32 | ### ❓ Что делает `~`?
33 |
34 | Оператор `~` — это **битовое НЕ (NOT)**. Он инвертирует **все биты числа**, т.е. `~n === -(n + 1)`.
35 |
36 | * `~1 = -2`
37 | * `~0 = -1`
38 | * `~-1 = 0` ← вот тут главное
39 |
40 | #### Пример:
41 |
42 | ```javascript
43 | let fruits = ["apple", "banana", "orange"];
44 | if (~fruits.indexOf("banana")) {
45 | console.log("Есть банан!");
46 | }
47 | ```
48 |
49 | **Пояснение:**
50 |
51 | * Если `"banana"` найден, `indexOf` возвращает `1`, `~1 === -2`, а `-2` — truthy.
52 | * Если элемент **не найден**, `indexOf` возвращает `-1`, `~-1 === 0`, а `0` — falsy.
53 |
54 | **Итого:** `~indexOf(...)` используется для проверки, **нашли ли элемент** в массиве, не сравнивая напрямую с `-1`.
55 |
56 | Но! Это **плохо читается** и считается **антипаттерном**. Лучше писать явно:
57 |
58 | ```javascript
59 | if (fruits.indexOf("banana") !== -1) { ... }
60 | ```
61 |
62 | или, в современном JavaScript:
63 |
64 | ```javascript
65 | if (fruits.includes("banana")) { ... } ✅
66 | ```
67 |
68 | ---
69 |
70 | ## 🔹 Побитовые операторы: Добро или Зло?
71 |
72 | ### ✅ Где они полезны:
73 |
74 | 1. **Флаги и маски**:
75 | Например, если вы используете бинарные флаги для прав доступа:
76 |
77 | ```javascript
78 | const READ = 1; // 0001
79 | const WRITE = 2; // 0010
80 | const EXECUTE = 4; // 0100
81 | let permissions = READ | WRITE;
82 |
83 | if (permissions & READ) { console.log("Чтение разрешено"); }
84 | ```
85 |
86 | 2. **Оптимизация (очень низкоуровневая)**:
87 | Используются, когда важна производительность, особенно в играх, шейдерах, численных вычислениях.
88 |
89 | 3. **Работа с битовыми структурами, буферами и WebAssembly**.
90 |
91 | ---
92 |
93 | ### ❌ Когда они вредны:
94 |
95 | * В **обычном прикладном коде** (UI, бизнес-логика) они **ухудшают читаемость**.
96 | * `~indexOf` — **непонятная магия**, особенно для начинающих.
97 | * Побитовые операторы могут вести к **непредсказуемым ошибкам**, если вы случайно примените их к нечисловым типам (например, строкам).
98 |
99 | ---
100 |
101 | ## 🎯 Итог
102 |
103 | * Побитовые операторы (`&`, `|`, `~`, `^`, `<<`, `>>`) — **мощный, но нишевый инструмент**.
104 | * Они **не зло сами по себе**, но **их злоупотребление** в неправильном контексте приводит к плохому коду.
105 | * Используйте их, **только когда это действительно нужно**, и делайте код максимально понятным.
106 |
107 | ## 🏆 ЗАДАЧИ
108 |
109 | Вот несколько **качественных задач для закрепления** темы **побитовых операторов** (`&`, `|`, `~`, `^`, `<<`, `>>`) и обсуждённой идиомы `~indexOf()`.
110 |
111 | ---
112 |
113 | ### 📌 Задача 1: Флаги прав доступа
114 |
115 | У вас есть флаги доступа:
116 |
117 | ```javascript
118 | const READ = 1; // 0001
119 | const WRITE = 2; // 0010
120 | const EXECUTE = 4; // 0100
121 | ```
122 |
123 | Создайте переменную `userPermissions`, в которой разрешены `READ` и `WRITE`. Проверьте, имеет ли пользователь доступ на `EXECUTE`.
124 |
125 | ```javascript
126 | const userPermissions = READ | WRITE;
127 |
128 | console.log(userPermissions & EXECUTE); // ?
129 | ```
130 |
131 |
132 | ✍ Решение
133 |
134 | ```javascript
135 | console.log(userPermissions & EXECUTE); // 0 (нет EXECUTE)
136 | ```
137 |
138 |
139 |
140 | ---
141 |
142 | ### 📌 Задача 2: Быстрая проверка наличия элемента через `~indexOf`
143 |
144 | ```javascript
145 | const fruits = ["apple", "banana", "grape"];
146 |
147 | if (~fruits.indexOf("banana")) {
148 | console.log("🍌 Банан найден!");
149 | } else {
150 | console.log("❌ Банана нет.");
151 | }
152 |
153 | if (~fruits.indexOf("melon")) {
154 | console.log("🍈 Дыня найдена!");
155 | } else {
156 | console.log("❌ Дыни нет.");
157 | }
158 | ```
159 |
160 |
161 | ✅ Вывод
162 |
163 | ```javascript
164 | 🍌 Банан найден!
165 | ❌ Дыни нет.
166 | ```
167 |
168 |
169 |
170 | ---
171 |
172 | ### 📌 Задача 3: Побитовая маска прав
173 |
174 | ```javascript
175 | const ADMIN = 1 << 0; // 0001
176 | const MODERATOR = 1 << 1; // 0010
177 | const USER = 1 << 2; // 0100
178 |
179 | let role = ADMIN | USER; // пользователь — админ и обычный пользователь
180 |
181 | // Проверка: является ли он модератором?
182 | console.log(Boolean(role & MODERATOR)); // ?
183 | ```
184 |
185 |
186 | ✅ Вывод
187 |
188 | ```javascript
189 | false // MODERATOR не включён в роль
190 | ```
191 |
192 |
193 |
194 | ---
195 |
196 | ### 📌 Задача 4: XOR-свап без временной переменной
197 |
198 | Поменяйте местами значения двух переменных без использования третьей переменной:
199 |
200 | ```javascript
201 | let a = 10;
202 | let b = 20;
203 |
204 | // Используйте побитовый XOR
205 | a = a ^ b;
206 | b = a ^ b;
207 | a = a ^ b;
208 |
209 | console.log(a); // ?
210 | console.log(b); // ?
211 | ```
212 |
213 |
214 | ✅ Вывод
215 |
216 | ```javascript
217 | a = 20
218 | b = 10
219 | ```
220 |
221 |
222 |
223 | ---
224 |
225 | ### 📌 Задача 5: Убедись, что `indexOf` не возвращает `-1`
226 |
227 | Проверь результат `~` для различных `indexOf()`:
228 |
229 | ```javascript
230 | console.log(~(-1)); // ?
231 | console.log(~0); // ?
232 | console.log(~1); // ?
233 | ```
234 |
235 |
236 | ✅ Вывод
237 |
238 | ```javascript
239 | ~(-1) = 0
240 | ~0 = -1
241 | ~1 = -2
242 | ```
243 |
244 |
245 |
246 | ---
247 |
248 | 🎉 Эти задачи помогут лучше понять:
249 |
250 | * где использовать побитовые операторы уместно;
251 | * как читать старые конструкции типа `~indexOf`;
252 | * как безопасно и правильно проверять роли, флаги, состояния.
253 |
254 | ---
255 |
--------------------------------------------------------------------------------
/11.JS-Browser/ 7.Всплытие событий в DOM.md:
--------------------------------------------------------------------------------
1 | # 📌 Всплытие событий в DOM
2 |
3 | ### 🔹 Что это такое?
4 |
5 | **Всплытие событий (event bubbling)** — это механизм распространения событий в DOM. Когда событие происходит на вложенном элементе, оно сначала обрабатывается на этом элементе, а затем поднимается вверх по иерархии DOM, вызывая обработчики на родительских элементах.
6 |
7 | ---
8 |
9 | ### 🔹 Как это работает?
10 |
11 | #### Пример:
12 |
13 | ```html
14 |
15 |
16 |
17 | ```
18 |
19 | ```javascript
20 | document.getElementById('parent').addEventListener('click', () => {
21 | console.log('Parent clicked');
22 | });
23 |
24 | document.getElementById('child').addEventListener('click', () => {
25 | console.log('Child clicked');
26 | });
27 | ```
28 |
29 | **При клике по кнопке в консоли появится:**
30 |
31 | ```
32 | Child clicked
33 | Parent clicked
34 | ```
35 |
36 | Сначала срабатывает обработчик на кнопке (`child`), затем на контейнере (`parent`).
37 |
38 | ---
39 |
40 | ### 🔹 Как остановить всплытие?
41 |
42 | Чтобы остановить распространение события выше по дереву, используйте:
43 |
44 | #### `stopPropagation()`
45 |
46 | ```javascript
47 | document.getElementById('child').addEventListener('click', function(event) {
48 | console.log('Child clicked');
49 | event.stopPropagation(); // Остановить всплытие
50 | });
51 | ```
52 |
53 | #### `stopImmediatePropagation()`
54 |
55 | Останавливает всплытие и предотвращает выполнение других обработчиков на этом же элементе:
56 |
57 | ```javascript
58 | element.addEventListener('click', function(event) {
59 | event.stopImmediatePropagation();
60 | });
61 | ```
62 |
63 | ---
64 |
65 | ### 🔹 Когда это полезно?
66 |
67 | * Чтобы обработчик родительского элемента **не реагировал** на события внутри вложенного.
68 | * Для создания **гибкого управления** событиями в сложных интерфейсах.
69 |
70 | ---
71 |
72 | ## 🎯 Итог
73 |
74 | Всплытие событий позволяет событиям подниматься от цели к предкам. Используя `stopPropagation()` и `stopImmediatePropagation()`, можно точно управлять маршрутом события и исключать нежелательные реакции.
75 |
76 | ## 🏆 ЗАДАЧИ
77 |
78 | Задачи по теме `Всплытие событий в DOM`
79 |
80 | ---
81 |
82 | Вот переработанный и единообразно оформленный список задач по теме **всплытие событий в DOM** — с чёткими описаниями, которые точно дают понять, что нужно сделать. Решения находятся под спойлером, чтобы пользователь мог сначала попытаться сам.
83 |
84 | ---
85 |
86 | ### 📌 Задача 1: Блокировка всплытия
87 |
88 | В документе есть `div#outer`, внутри которого находится `button#inner`. При клике на кнопку должно появляться сообщение `"Button clicked"` и **не должно** появляться сообщение `"Div clicked"`.
89 |
90 | ```html
91 |
92 |
93 |
94 | ```
95 |
96 |
97 | ✍ Решение
98 |
99 | ```javascript
100 | document.getElementById('outer').addEventListener('click', () => {
101 | console.log('Div clicked');
102 | });
103 |
104 | document.getElementById('inner').addEventListener('click', (e) => {
105 | console.log('Button clicked');
106 | e.stopPropagation();
107 | });
108 | ```
109 |
110 |
111 |
112 | Используем `stopPropagation()`, чтобы остановить всплытие события от кнопки к родительскому `div`.
113 |
114 | ---
115 |
116 | ### 📌 Задача 2: Делегирование обработчиков
117 |
118 | На странице есть список `
` с несколькими `
`. Нужно навесить один обработчик **только на `ul`**, который при клике на любую из `li` выводит текст выбранного элемента (например, `Clicked: Item 2`).
119 |
120 | ```html
121 |
122 |
Item 1
123 |
Item 2
124 |
Item 3
125 |
126 | ```
127 |
128 |
129 | ✍ Решение
130 |
131 | ```javascript
132 | document.getElementById('list').addEventListener('click', (e) => {
133 | if (e.target.tagName === 'LI') {
134 | console.log('Clicked:', e.target.textContent);
135 | }
136 | });
137 | ```
138 |
139 |
140 |
141 | Используем всплытие событий и делегирование, чтобы обрабатывать клики на дочерних элементах через родительский.
142 |
143 | ---
144 |
145 | ### 📌 Задача 3: Отключение лишних обработчиков
146 |
147 | На кнопке `button#btn` навешены два обработчика события `click`. Нужно, чтобы срабатывал только первый и второй не выполнялся.
148 |
149 | ```html
150 |
151 | ```
152 |
153 |
154 | ✍ Решение
155 |
156 | ```javascript
157 | const btn = document.getElementById('btn');
158 |
159 | btn.addEventListener('click', (e) => {
160 | console.log('First handler');
161 | e.stopImmediatePropagation();
162 | });
163 |
164 | btn.addEventListener('click', () => {
165 | console.log('Second handler');
166 | });
167 | ```
168 |
169 |
170 |
171 | Метод `stopImmediatePropagation()` прерывает не только всплытие, но и последующие обработчики на том же элементе.
172 |
173 | ---
174 |
175 | ### 📌 Задача 4: Показать цепочку всплытия
176 |
177 | **Что нужно сделать:**
178 | Дано три вложенных блока: `#grandparent`, `#parent`, `#child`. Каждый из них должен логировать сообщение при клике. Нужно убедиться, что кликая на `#child`, вы увидите в консоли **последовательность всплытия** от внутреннего элемента к внешнему.
179 |
180 | ```html
181 |
182 |
183 |
Click here
184 |
185 |
186 | ```
187 |
188 |
189 | ✍ Решение
190 |
191 | ```javascript
192 | document.getElementById('grandparent').addEventListener('click', () => {
193 | console.log('Grandparent clicked');
194 | });
195 | document.getElementById('parent').addEventListener('click', () => {
196 | console.log('Parent clicked');
197 | });
198 | document.getElementById('child').addEventListener('click', () => {
199 | console.log('Child clicked');
200 | });
201 | ```
202 |
203 |
204 |
205 | Всплытие идёт снизу вверх — от `child` к `parent` и далее к `grandparent`.
206 |
207 | ---
208 |
209 | 🎉 Управление всплытием — это инструмент, который даёт гибкость в обработке событий и помогает избежать конфликтов между обработчиками разных уровней DOM.
210 |
211 | ---
212 |
--------------------------------------------------------------------------------
/11.JS-Browser/0.Введение в JavaScript для браузера.md:
--------------------------------------------------------------------------------
1 | # 📌 Введение в JavaScript для браузера (JS-Browser)
2 |
3 | JavaScript — это язык программирования, который оживляет веб-страницы. В связке с HTML и CSS он играет ключевую роль на стороне клиента, управляя поведением элементов на странице в браузере пользователя. Именно в браузере JavaScript получает доступ к **DOM (Document Object Model)** — мосту между структурой HTML-документа и возможностями динамического взаимодействия.
4 |
5 | ### ❓ Что такое JavaScript в браузере?
6 |
7 | Когда вы открываете веб-страницу, браузер сначала загружает HTML и CSS, формируя статичное представление страницы. Затем он запускает JavaScript, который может:
8 |
9 | * изменять содержимое и структуру страницы;
10 | * реагировать на действия пользователя (клики, ввод данных и т.д.);
11 | * отправлять и получать данные с сервера без перезагрузки страницы (AJAX, Fetch API);
12 | * управлять мультимедиа, стилями, анимациями и многим другим.
13 |
14 | Это делает JavaScript незаменимым инструментом для создания **интерактивных и отзывчивых пользовательских интерфейсов**.
15 |
16 | ---
17 |
18 | ## Ключевые концепции JS в браузере
19 |
20 | ### 🔹 1. **DOM (Document Object Model)**
21 |
22 | DOM — это объектное представление HTML-документа в виде дерева. С его помощью JavaScript может:
23 |
24 | * находить элементы (`getElementById`, `querySelector`);
25 | * изменять содержимое (`element.textContent`, `innerHTML`);
26 | * добавлять или удалять элементы (`createElement`, `appendChild`, `removeChild`);
27 | * управлять атрибутами, классами и стилями.
28 |
29 | #### Пример:
30 |
31 | ```javascript
32 | const title = document.querySelector('h1');
33 | title.textContent = 'Новый заголовок!';
34 | ```
35 |
36 | ### 🔹 2. **Обработка событий**
37 |
38 | JavaScript позволяет "слушать" действия пользователя и реагировать на них:
39 |
40 | ```javascript
41 | button.addEventListener('click', () => {
42 | alert('Кнопка нажата!');
43 | });
44 | ```
45 |
46 | События могут быть самыми разными: нажатие клавиши, прокрутка страницы, наведение мыши, отправка формы и т.д.
47 |
48 | ### 🔹 3. **Манипуляции со стилями**
49 |
50 | Скрипт может менять внешний вид элементов прямо во время работы страницы:
51 |
52 | ```javascript
53 | element.style.color = 'red';
54 | element.classList.add('active');
55 | ```
56 |
57 | ---
58 |
59 | ## Взаимодействие с сервером
60 |
61 | JS в браузере умеет делать запросы к серверу — загружать данные, изображения, и даже отправлять формы **без перезагрузки страницы**:
62 |
63 |
64 | ```javascript
65 | fetch('/api/data')
66 | .then(response => response.json())
67 | .then(data => console.log(data));
68 | ```
69 |
70 | ---
71 |
72 | #### Пример: динамическое изменение текста
73 |
74 | ```html
75 |
Добро пожаловать!
76 |
77 |
78 |
86 | ```
87 |
88 | При нажатии на кнопку текст заголовка изменится — и всё это без перезагрузки страницы!
89 |
90 | ---
91 |
92 | ## 🎯 Итог
93 |
94 | JavaScript в браузере — это мощный инструмент, который позволяет создавать интерактивные веб-приложения. С его помощью вы можете:
95 |
96 | * управлять содержимым и структурой HTML;
97 | * реагировать на действия пользователя;
98 | * динамически изменять стили;
99 | * обмениваться данными с сервером.
100 |
101 | Это основа современного фронтенд-разработчика. Изучив работу JavaScript в браузере и взаимодействие с DOM, вы сможете создавать по-настоящему живые и удобные интерфейсы.
102 |
103 | ---
104 |
--------------------------------------------------------------------------------
/11.JS-Browser/1.событие в JavaScript и Event Handling.md:
--------------------------------------------------------------------------------
1 | # ❓ Что такое событие в JavaScript и как работает Event Handling?
2 |
3 | В JavaScript **событие** — это сигнал от браузера о том, что что-то произошло. Это может быть клик пользователя, загрузка страницы, ввод текста, движение мыши, нажатие клавиши и многое другое.
4 |
5 | **Event Handling (обработка событий)** — это процесс, при котором вы указываете, что делать, когда происходит определённое событие. Это важнейший механизм для создания **интерактивных веб-страниц**.
6 |
7 | ---
8 |
9 | ### Основные понятия
10 |
11 | #### 🔹 1. **Событие (Event)**
12 |
13 | Событие возникает при каком-либо действии:
14 |
15 | * `click` — пользователь кликнул мышью.
16 | * `dblclick` - двойное нажатие.
17 | * `keydown` — нажата клавиша.
18 | * `submit` — отправка формы.
19 | * `load` — загрузка страницы.
20 | * `mouseover`, `mouseout` — наведение/уход курсора и т. д.
21 |
22 | #### 🔹 2. **Обработчик события (Event Listener)**
23 |
24 | Это функция, которая вызывается при наступлении события. Вы можете привязать обработчик к конкретному элементу.
25 |
26 | ```javascript
27 | element.addEventListener('click', function() {
28 | // Код, который выполнится при клике
29 | });
30 | ```
31 |
32 | #### 🔹 3. **Удаление обработчиков**
33 |
34 | Вы также можете удалить обработчик, если он больше не нужен:
35 |
36 | ```javascript
37 | element.removeEventListener('click', handler);
38 | ```
39 |
40 | #### 🔹 4. **Анонимные и именованные функции**
41 |
42 | Вы можете использовать анонимные функции (как в примере выше) или именованные:
43 |
44 | ```javascript
45 | function handleClick() {
46 | console.log('Clicked!');
47 | }
48 | element.addEventListener('click', handleClick);
49 | ```
50 |
51 | ---
52 |
53 | ### Поток событий
54 |
55 | Когда событие происходит, браузер создаёт **объект события** (`Event object`) и передаёт его обработчику. Он содержит всю информацию о событии: тип, целевой элемент (`event.target`), координаты мыши, нажатые клавиши и т. д.
56 |
57 | ```javascript
58 | button.addEventListener('click', function(event) {
59 | console.log(event.target); // элемент, на котором произошло событие
60 | });
61 | ```
62 |
63 | ---
64 |
65 | #### Пример: обработка клика
66 |
67 | ```html
68 |
69 |
75 | ```
76 |
77 | ---
78 |
79 | ### Делегирование событий
80 |
81 | Вместо назначения обработчиков каждому элементу, можно использовать **делегирование** — назначать обработчик на родительский элемент и проверять, где именно произошло событие.
82 |
83 | ```javascript
84 | document.body.addEventListener('click', function(event) {
85 | if (event.target.matches('button')) {
86 | console.log('Кнопка нажата:', event.target.textContent);
87 | }
88 | });
89 | ```
90 |
91 | Это удобно при работе с динамически создаваемыми элементами.
92 |
93 | ---
94 |
95 | ### Предотвращение действий по умолчанию и всплытия
96 |
97 | * `event.preventDefault()` — отменяет поведение по умолчанию (например, отправку формы).
98 | * `event.stopPropagation()` — останавливает "всплытие" события вверх по DOM-дереву.
99 |
100 | ---
101 |
102 | ## 🎯 Итог
103 |
104 | События лежат в основе **взаимодействия пользователя с веб-приложением**. Понимание событий и умение правильно их обрабатывать позволяет создавать **реактивный, динамичный интерфейс**, который реагирует на действия пользователя в реальном времени.
105 |
106 | ## 🏆 ЗАДАЧИ
107 |
108 | Задачи по теме `события Event Handling в JavaScript`
109 |
110 | ---
111 |
112 | ### 📌 Задача 1: Клик по кнопке
113 |
114 | Создайте кнопку, при клике на которую в консоль выводится сообщение `Кнопка нажата!`.
115 |
116 | ```html
117 |
118 |
121 | ```
122 |
123 |
124 | ✍ Решение
125 |
126 | ```javascript
127 | document.getElementById('btn').addEventListener('click', function () {
128 | console.log('Кнопка нажата!');
129 | });
130 | ```
131 |
132 |
133 |
134 | ---
135 |
136 | ### 📌 Задача 2: Изменение текста при клике
137 |
138 | При клике на кнопку измените текст заголовка с `"Привет"` на `"Вы нажали кнопку!"`.
139 |
140 | ```html
141 |
Привет
142 |
143 |
146 | ```
147 |
148 |
149 | ✍ Решение
150 |
151 | ```javascript
152 | document.getElementById('change').addEventListener('click', function () {
153 | document.getElementById('title').textContent = 'Вы нажали кнопку!';
154 | });
155 | ```
156 |
157 |
158 |
159 | ---
160 |
161 | ### 📌 Задача 3: Предотвращение отправки формы
162 |
163 | Создайте форму с одной кнопкой. При её отправке не должно происходить перезагрузки страницы. Вместо этого выведите `Форма отправлена` в консоль.
164 |
165 | ```html
166 |
169 |
172 | ```
173 |
174 |
175 | ✍ Решение
176 |
177 | ```javascript
178 | document.getElementById('myForm').addEventListener('submit', function (e) {
179 | e.preventDefault();
180 | console.log('Форма отправлена');
181 | });
182 | ```
183 |
184 |
185 |
186 | ---
187 |
188 | ### 📌 Задача 4: Делегирование событий
189 |
190 | Есть список элементов. Выведите текст элемента, по которому кликнули.
191 |
192 | ```html
193 |
194 |
Элемент 1
195 |
Элемент 2
196 |
Элемент 3
197 |
198 |
201 | ```
202 |
203 |
204 | ✍ Решение
205 |
206 | ```javascript
207 | document.getElementById('list').addEventListener('click', function (e) {
208 | if (e.target.tagName === 'LI') {
209 | console.log('Вы нажали на:', e.target.textContent);
210 | }
211 | });
212 | ```
213 |
214 |
215 |
216 | ---
217 |
218 | ### 📌 Задача 5: Двойной клик
219 |
220 | Создайте обработчик, который меняет фон страницы на зелёный при **двойном клике**.
221 |
222 | ```html
223 |
224 |
227 |
228 | ```
229 |
230 |
231 | ✍ Решение
232 |
233 | ```javascript
234 | document.body.addEventListener('dblclick', function () {
235 | document.body.style.backgroundColor = 'green';
236 | });
237 | ```
238 |
239 |
240 |
241 | ---
242 |
243 | 🎉 Эти задачи помогут вам научиться слушать действия пользователя и реагировать на них с помощью JavaScript. Это ключевой шаг к созданию динамичных и интерактивных интерфейсов.
244 |
245 | ---
246 |
--------------------------------------------------------------------------------
/11.JS-Browser/2.Методы доступа к DOM-элементам.md:
--------------------------------------------------------------------------------
1 | # 📌 Методы доступа к DOM-элементам
2 |
3 | JavaScript предоставляет несколько способов найти и получить доступ к HTML-элементам на странице. Они отличаются по способу поиска, типу возвращаемого значения и удобству использования. Ниже приведены наиболее часто используемые методы.
4 |
5 | ---
6 |
7 | ### 🔹 1. `document.getElementById(id)`
8 |
9 | * **Что делает**: Ищет элемент по его `id`.
10 | * **Особенности**: Возвращает **один** элемент или `null`, если ничего не найдено.
11 | * **Тип возвращаемого значения**: `HTMLElement`.
12 |
13 | ---
14 |
15 | ### 🔹 2. `document.getElementsByClassName(className)`
16 |
17 | * **Что делает**: Находит все элементы с указанным классом.
18 | * **Особенности**:
19 |
20 | * Возвращает `HTMLCollection`, похожую на массив, но без методов массива.
21 | * Результат "живой" — если элементы добавлены/удалены, коллекция обновляется автоматически.
22 |
23 | ---
24 |
25 | ### 🔹 3. `document.getElementsByTagName(tagName)`
26 |
27 | * **Что делает**: Возвращает все элементы с указанным тегом (например, `div`, `p`, `li`).
28 | * **Особенности**: Также возвращает "живую" `HTMLCollection`.
29 |
30 | ---
31 |
32 | ### 🔹 4. `document.querySelector(selector)`
33 |
34 | * **Что делает**: Возвращает **первый** элемент, соответствующий CSS-селектору (например, `.class`, `#id`, `div > p`, `[name=value]` и т. д.).
35 | * **Особенности**:
36 |
37 | * Очень гибкий, так как можно использовать любой валидный CSS-селектор.
38 | * Возвращает `null`, если ничего не найдено.
39 |
40 | ---
41 |
42 | ### 🔹 5. `document.querySelectorAll(selector)`
43 |
44 | * **Что делает**: Возвращает **все** элементы, соответствующие CSS-селектору.
45 | * **Тип возвращаемого значения**: `NodeList`, который поддерживает `forEach()`, `entries()` и другие методы.
46 | * **Особенности**: Результат **не живой** — если вы измените DOM, `NodeList` не обновится.
47 |
48 | ---
49 |
50 | ### Родственные свойства для навигации по дереву DOM
51 |
52 | ---
53 |
54 | ### 🔹 6. `element.parentNode`
55 |
56 | * **Что делает**: Получает родительский узел указанного элемента.
57 | * **Применение**: Полезно при делегировании событий или изменении структуры DOM.
58 |
59 | ---
60 |
61 | ### 🔹 7. `element.children`
62 |
63 | * **Что делает**: Возвращает только дочерние элементы (теги, но не текстовые узлы).
64 | * **Тип**: `HTMLCollection`.
65 |
66 | Дополнительно:
67 |
68 | * `childNodes` — включает **все** дочерние узлы, включая текст, комментарии и т.д.
69 | * `firstElementChild`, `lastElementChild` — удобные способы обратиться к первому/последнему дочернему элементу.
70 | * `nextElementSibling`, `previousElementSibling` — позволяют перемещаться между соседними элементами.
71 |
72 | ---
73 |
74 | ### ❓ Когда что использовать?
75 |
76 | | Цель | Метод |
77 | | ------------------------------------ | -------------------------- |
78 | | Быстро получить элемент по ID | `getElementById()` |
79 | | Получить элементы по классу | `getElementsByClassName()` |
80 | | Получить элементы по тегу | `getElementsByTagName()` |
81 | | Точный выбор с помощью CSS-селектора | `querySelector()` |
82 | | Множественный выбор с селектором | `querySelectorAll()` |
83 |
84 | ---
85 |
86 | ## 🎯 Итог
87 |
88 | Эти методы — основа работы с DOM в JavaScript. Их знание и правильное применение позволяет:
89 |
90 | * Изменять содержимое страницы на лету.
91 | * Реагировать на действия пользователя.
92 | * Управлять структурой и визуальным отображением элементов.
93 |
94 | Если ты будешь уверенно различать `getElementById`, `querySelector`, `children` и `parentNode` — ты уже на хорошем пути к созданию интерактивных веб-приложений.
95 |
96 | ## 🏆 ЗАДАЧИ
97 |
98 | Задачи по теме `Методы доступа к DOM-элементам`
99 |
100 | ---
101 |
102 | ### 📌 Задача 1: Получение элемента по ID
103 |
104 | Найдите элемент с идентификатором `greeting` и измените его текст на "**Привет, JavaScript!**" с помощью JavaScript.
105 |
106 | ```html
107 |
Привет, мир!
108 | ```
109 |
110 |
111 | ✍ Решение
112 |
113 | ```javascript
114 | const element = document.getElementById('greeting');
115 | element.textContent = 'Привет, JavaScript!';
116 | ```
117 |
118 | Метод `getElementById()` позволяет получить доступ к конкретному элементу по его атрибуту `id`. После этого с помощью свойства `textContent` мы изменяем содержимое параграфа.
119 |
120 |
121 |
122 | ---
123 |
124 | ### 📌 Задача 2: Работа с классами
125 |
126 | Получите все элементы с классом `item` и выведите в консоль текст второго элемента.
127 |
128 | ```html
129 |
Первый
130 |
Второй
131 |
Третий
132 | ```
133 |
134 |
135 | ✍ Решение
136 |
137 | ```javascript
138 | const items = document.getElementsByClassName('item');
139 | console.log(items[1].textContent); // Второй
140 | ```
141 | Метод `getElementsByClassName()` возвращает коллекцию элементов с указанным классом в виде `HTMLCollection`. Мы обращаемся к нужному элементу по индексу, начиная с 0.
142 |
143 |
144 |
145 | ---
146 |
147 | ### 📌 Задача 3: Использование `querySelector()
148 |
149 | Найдите первый элемент с классом `selected` и измените его текст на «**Активный пункт**».
150 |
151 | ```html
152 |
153 |
Выбранный пункт
154 |
Обычный пункт
155 |
156 | ```
157 |
158 |
159 | ✍ Решение
160 |
161 | ```javascript
162 | const selectedItem = document.querySelector('.selected');
163 | selectedItem.textContent = 'Активный пункт';
164 | ```
165 |
166 | `querySelector` возвращает первый найденный элемент по CSS-селектору.
167 |
168 |
169 |
170 | ---
171 |
172 | ### 📌 Задача 4: Перебор с `querySelectorAll()`
173 |
174 | Выберите все элементы с классом `menu` и добавьте в конец их текста восклицательный знак.
175 |
176 | ```html
177 |
178 |
Главная
179 |
О нас
180 |
Контакты
181 |
182 | ```
183 |
184 |
185 | ✍ Решение
186 |
187 | ```javascript
188 | const menuItems = document.querySelectorAll('.menu');
189 | menuItems.forEach(item => {
190 | item.textContent += '!';
191 | });
192 | ```
193 |
194 | `querySelectorAll` возвращает NodeList — можно использовать `forEach`.
195 |
196 |
197 |
198 | ---
199 |
200 | ### 📌 Задача 5: Навигация по DOM
201 |
202 | По элементу с идентификатором `child` получите родительский элемент и выведите его идентификатор в консоль.
203 |
204 | ```html
205 |
206 |
Я потомок
207 |
208 | ```
209 |
210 |
211 | ✍ Решение
212 |
213 | ```javascript
214 | const child = document.getElementById('child');
215 | const parent = child.parentNode;
216 | console.log(parent.id); // container
217 | ```
218 |
219 | Свойство `parentNode` возвращает родительский узел.
220 |
221 |
222 |
223 | ---
224 |
225 | ### 📌 Задача 6: Доступ к детям
226 |
227 | Получите первый дочерний элемент списка с идентификатором `list` и выведите его текст.
228 |
229 | ```html
230 |
231 |
Элемент 1
232 |
Элемент 2
233 |
234 | ```
235 |
236 |
237 | ✍ Решение
238 |
239 | ```javascript
240 | const list = document.getElementById('list');
241 | console.log(list.children[0].textContent); // Элемент 1
242 | ```
243 |
244 | `children` — коллекция дочерних элементов (не включает текст и комментарии).
245 |
246 |
247 |
248 | ---
249 |
250 | 🎉 Эти задачи помогут закрепить навыки работы с методами доступа к DOM-элементам в JavaScript и лучше понять, как находить, изменять и управлять содержимым HTML-страницы.
251 |
252 | ---
253 |
--------------------------------------------------------------------------------
/11.JS-Browser/3.Добавление, удаление и замена элементов.md:
--------------------------------------------------------------------------------
1 | # 📌 Работа с DOM: добавление, удаление и замена элементов
2 |
3 | JavaScript позволяет гибко управлять структурой HTML-документа через DOM. Ниже приведены основные методы для **добавления**, **удаления** и **замены** элементов.
4 |
5 | ---
6 |
7 | ### **1. Добавление элемента**
8 |
9 | Чтобы добавить новый элемент в DOM, сначала нужно его создать с помощью `document.createElement`, затем вставить в нужное место.
10 |
11 | #### 🔹 `appendChild()` — добавляет элемент в конец родителя
12 |
13 | ```html
14 |
15 |
Первый параграф
16 |
17 |
18 |
24 | ```
25 |
26 | *Добавляет элемент в конец указанного родительского узла.*
27 |
28 | ---
29 |
30 | #### 🔹 `insertBefore()` — вставляет элемент перед другим элементом
31 |
32 | ```javascript
33 | const newParagraph = document.createElement('p');
34 | newParagraph.textContent = 'Новый параграф перед первым';
35 | const firstParagraph = container.firstChild;
36 | container.insertBefore(newParagraph, firstParagraph);
37 | ```
38 |
39 | *Вставляет `newParagraph` перед `firstParagraph` в пределах `container`.*
40 |
41 | ---
42 |
43 | #### 🔹 `insertAdjacentElement()` — вставка по позициям
44 |
45 | ```javascript
46 | const newParagraph = document.createElement('p');
47 | newParagraph.textContent = 'Параграф в начале контейнера';
48 | container.insertAdjacentElement('afterbegin', newParagraph);
49 | ```
50 |
51 | *Позволяет вставлять в начало (`afterbegin`), конец (`beforeend`), перед (`beforebegin`) или после (`afterend`) элемента.*
52 |
53 | ---
54 |
55 | ### **2. Удаление элемента**
56 |
57 | Удалить элемент можно как напрямую, так и через родителя.
58 |
59 | #### 🔹 `remove()` — удаляет сам элемент
60 |
61 | ```html
62 |
Удалите меня
63 |
64 |
68 | ```
69 |
70 | *Удаляет сам себя из DOM.*
71 |
72 | ---
73 |
74 | #### 🔹 `parentNode.removeChild()` — удаление через родителя
75 |
76 | ```javascript
77 | const container = document.getElementById('container');
78 | const toRemove = document.getElementById('toRemove');
79 | container.removeChild(toRemove);
80 | ```
81 |
82 | *Полезно в старых браузерах, которые не поддерживают `remove()`.*
83 |
84 | ---
85 |
86 | ### **3. Замена элемента**
87 |
88 | #### 🔹 `replaceChild()` — заменяет один дочерний элемент другим
89 |
90 | ```html
91 |
92 |
Старый параграф
93 |
94 |
95 |
101 | ```
102 |
103 | *Метод `replaceChild(newNode, oldNode)` заменяет `oldNode` на `newNode` внутри родителя.*
104 |
105 | ---
106 |
107 | ## 🎯 Итог
108 |
109 | | Действие | Метод | Поддержка |
110 | | ---------- | ----------------------- | --------------------------- |
111 | | Добавление | `appendChild` | ✔ Стандартный способ |
112 | | Добавление | `insertBefore` | ✔ Гибкость позиционирования |
113 | | Добавление | `insertAdjacentElement` | ✔ Удобные позиции |
114 | | Удаление | `remove` | ✔ Современно и просто |
115 | | Удаление | `removeChild` | ✔ Универсальный способ |
116 | | Замена | `replaceChild` | ✔ Надёжный способ |
117 |
118 | ---
119 |
120 | 💡 **Примечание:** Всегда сначала создавайте элемент (`createElement`), задавайте ему содержимое (`textContent`, `innerHTML`, `classList` и т.д.), а затем вставляйте в DOM.
121 |
122 | ## 🏆 ЗАДАЧИ
123 |
124 | Задачи по теме `Добавление, удаление и замена элементов в DOM`
125 |
126 | ---
127 |
128 | ### 📌 Задача 1: Добавление параграфа
129 |
130 | Добавьте новый параграф с текстом `"Это добавленный текст"` в конец блока `#content`.
131 |
132 | ```html
133 |