REDEV JavaScript
REDEV JavaScript
Учебник по JavaScript
Перед стартом
🏅 0. Про JavaScript
🆕 0. Как запускать код?
1-й чек-лист
👽 1.1. Переменные
🌀 1.2. Типы данных
🎴 1.3. Операторы
📓 1.4. Циклы и Switch
🏆 1.5. Функции
2-й чек-лист
🕣 2.1. Числа
🌙 2.2. Строки
🚥 2.3. Объекты. Основы
🤯 2.4 Объекты. Углубиться
Учебник по JavaScript 1
3-й чек-лист
🛎 3.1. Массивы
🏕 3.2. Методы массивов
4-й чек-лист
☔ 4.1. ДП + spread
🧵 4.2. JSON
⚠ 4.3. try…catch...finally
🪧 4.4. Прототип
🗓 4.5. Дата и время
💥 4.6. Коллекции. Map и Set
➿ 4.7. Замыкание. Рекурсия. Каррирование
5-й чек-лист
🏛 5.1. class
🪧 5.2. ООП в JavaScript
6-й чек-лист
Учебник по JavaScript 2
6.3. Promise
🔄 6.4. async/await
🔂 6.5. Event Loop
🌐 6.6. HTTP (fetch)
Учебник по JavaScript 3
🏅
0. Про JavaScript
JavaScript - это язык программирования, который используется для создания
динамических веб-страниц. Он может быть использован для добавления
интерактивности и функциональности на сайт, включая обработку событий,
манипуляцию элементами на странице, и многое другое. JavaScript также может
быть использован для создания веб-приложений , мобильных приложений и
десктопных приложений. В 2023 году он был самым популярным языком
программирования, используемым в 70% всех проектов.
0. Про JavaScript 1
История
JavaScript был создан в 1995 году Бренданом Айком в компании Netscape
Communications Corporation. Он был разработан как язык программирования для
обработки веб-страниц на стороне клиента, то есть на компьютере пользователя.
Изначально он назывался Mocha , затем LiveScript , а в конечном итоге был
переименован в JavaScript .
Название JavaScript было выбрано для создания ассоциации с Java , который на
тот момент был очень популярен. Однако, несмотря на сходство в названии,
JavaScript и Java являются разными языками программирования с разной
0. Про JavaScript 2
Текущая версия JavaScript - это ECMAScript 2021 (ES2021), которая была
выпущена в июне 2021 года.
0. Про JavaScript 3
🆕
0. Как запускать код?
Существует множество онлайн редакторов для JavaScript, которые могут быть
использованы для написания JavaScript кода. Некоторые из наиболее популярных
онлайн редакторов для JavaScript:
1. CodePen (https://codepen.io/)
2. JSFiddle (https://jsfiddle.net/)
3. Repl.it (https://repl.it/)
4. JS Bin (https://jsbin.com/)
5. Glitch (https://glitch.com/)
6. StackBlitz (https://stackblitz.com/)
Я рекомендую писать сразу в VSCode или WebStorm чтобы привыкать к работе с ним.
Я использую VSCode.
Способ #1
Для запуска JavaScript кода в VSCode необходимо установить расширение Code
1. Открой VSCode .
6. Нажми Ctrl + Alt + N или нажмите на кнопку Play в правом верхнем углу
редактора.
Способ #2
Для запуска JavaScript кода в VSCode необходимо установить node.js.
1. Открой VSCode .
Если увидишь версию, как в примере выше, то все отлично. Можно работать!
Видео:
https://youtu.be/bAcu9ymOoRc
1.1. Переменные 1
let appleCount = 6;
console.log(appleCount); //выводит 6
let
const
var
let num = 5;
const str = "Redev";
var isAdmin = true;
Это означает, что при объявлении переменной или функции необходимо быть
внимательным к регистру и использовать их обдуманно во всем коде. Иначе это
может привести к ошибкам и непредсказуемому поведению кода.
1.1. Переменные 2
Осознанное именование переменных в JavaScript является важным аспектом
программирования, поскольку оно помогает сделать код более читаемым и
понятным.
camelCase и snake_case
1.1. Переменные 3
Имена переменных могут состоять из нескольких слов! Что делать в таком
случае? Как именовать переменные? Вот ответ
let num = 5;
num = 6;// значение переменной num изменится
const num = 5;
num = 6; // будет ошибка
1.1. Переменные 4
var num = 10;
var num = 15;
console.log(num);// переменная просто перезапишется и будет 15
2. Область видимости.
У let она блочная, а у var функциональная. То есть let ограничивается
ЛЮБЫМИ ФИГУРНЫМИ скобками, а var только функцией.
{
let num = 1;
console.log(num); // тут переменная будет видна
}
console.log(num); // тут уже будет ошибка
------------------------------------------------------
{
var num = 1;
console.log(num); // тут переменная будет видна
}
console.log(num); // и тут тоже переменная будет видна
------------------------------------------------------
function func(){
var num = 1;
console.log(num); // тут переменная будет видна
}
console.log(num); // тут уже будет ошибка
3. Hoisting.
Hoisting - это механизм, который позволяет JavaScript поднимать объявления
переменных в начало текущего контекста выполнения. В результате этого
переменные могут использоваться до того, как они объявлены в коде.
ВАЖНО: при этом значение ее будет undefined (пустота)!
Если же попробовать достучаться до объявленной переменной с помощью let,
то будет ошибка.
console.log(num);// undefined
var num = 10;
1.1. Переменные 5
console.log(num);// ошибка
let num = 10;
Итого:
1. Есть 3 способа объявить переменную ( let , const , var )
3. Регистр важен!
1.1. Переменные 6
4. Лучше использовать camelCase чем snake_case
Задания
1. Создай две переменные с именами name и age и присвой им любые значения.
console.log(age);//?
let age = 25;
1.1. Переменные 7
console.log(age);//?
var age = 25;
1.1. Переменные 8
🌀
1.2. Типы данных
В JavaScript существует 8 типов данных. Про каждый подробно мы поговорим
в следующих главах, а пока их надо выучить:
7. bigInt- биг инт - большое число (для работы с очень большими целыми
числами);
Оператор typeof
let num = 1;
typeof num; // "number"
let abc;
typeof abc; // "undefined"
function func(){}
typeof func; // "function" !!!
Почему “string” ?
Потому что, typeof age вернет “number” , а typeof “number” вернет “string”.
Потому что, typeof isMan вернет “boolean” , а typeof “boolean” вернет “string”.
2. https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Operators/typeof
Задания
1. Чему будет равно выражение typeof -5; ?
🎴 1.3. Операторы
1. Математические
2. Сравнения
3. Условные
4. Логические
Надо разобраться, что такое операнд и оператор, прежде чем идти дальше!
В JavaScript операнд - это значение, которое обрабатывается оператором.
Операнды могут быть любым типом данных, например, числами, строками, объектами
и т.д.
Например, в выражении 5 + 2 , 5 и 2 являются операндами, а + является
оператором.
Каждый оператор имеет свой синтаксис и правила использования, и результат их
выполнения может быть разным в зависимости от типа операндов.
Математические
+ // плюс
- // минус
* // умножить
/ // разделить
% // остаток от деления
** // возведение в степень
Если с первыми четырьмя все понятно (если нет, то ты зря купил курс 🤔 ), то про
два последних поговорим.
1.3. Операторы 1
% - это остаток от деления и он возвращает остаток от целочисленного деления. Тихо
тихо…сейчас поясню.
Возьмем пример console.log(5%2). В консоли увидим 1, так как 5 можно расписать как
2+2+1, двойки сократили, потому что берем %2 и остается 1.
console.log(2**2);//4 (2*2)
console.log(5**3);//125 (5*5*5)
console.log(3**3);//27 (3*3*3)
Операторы сравнения
> // больше
< // меньше
>= // больше или равно
<= // меньше или равно
== // равно
=== // строгое равно
!= // не равно
!== // строгое не равно
1.3. Операторы 2
Разница простая: строгое равно (===) учитывает типы данных при сравнении, а не
строгое равно (==) приводит все к одному типу (числу).
1. Оператор != :
let x = 5;
let y = "5";
console.log(x != y); // false
let a = 10;
let b = 20;
console.log(a != b); // true
2. Оператор !== :
let x = 5;
let y = "5";
console.log(x !== y); // true
let a = 10;
let b = "10";
console.log(a !== b); // true
let a = 5;
1.3. Операторы 3
let b = 5;
console.log(a !== b); // false
if(условие){
//тело
} else {
//тело
}
const a = 5;
if(a>3){
console.log("верно");
} else {
console.log("не верно");
}
Тернарный оператор работает точно так же и читается точно так же, просто
синтаксис другой. Смотри
const a = 5;
a>3 ? console.log("верно") : console.log("не верно");
1.3. Операторы 4
Пояснение:
name === "redev" ? console.log(❤) // так нельяза писать, javascript будет ругаться
name === "redev" ? console.log(❤) : console.log(😭); // так правильно
Логические операторы
&& - и
|| - или
! - не
1.3. Операторы 5
! - не
Приводит к boolean и возвращает противоположное.
console.log(!true);// false
console.log(!false);// true
console.log(!5);// false. 5 приводит к boolean, это true, противоположное это false
console.log(!0);// true. 0 приводит к boolean, это false, противоположное это true
console.log(!"redev");// false. "redev" приводит к boolean, это true, противоположное это false
console.log(!"");// true. "" приводит к boolean, это false, противоположное это true
0 - ноль
“” - пустая строка
undefined - пустота
null - пустота
NaN - не число
и сам false
!!true = true
!!false = false
!!0 = false
!!1 = true
!!'' = false
!!'text' = true
Таким образом, "!!" может использоваться для преобразования значений, таких как
строки или числа и т.д. в логические значения.
&& - и
Возвращает первый false или последний true.
1.3. Операторы 6
console.log(2 && 0);// 0, потому что 2-true,а 0-false.
console.log(2 && 4);// 4, потому что 2-true,4-true и возвращает последний true.
console.log(0 && "redev");// 0, потому что 0-false и возвращает первый false.
console.log(3 && null && "redev");;// null
//3 - true
//null - false
//"redev" - true
Возвращает первый false то есть null
|| - или
Возвращает первый true или последний false.
//3 - true
//null - false
//"redev" - true
Возвращает первый true то есть 3
1. !
2. &&
3. ||
1.3. Операторы 7
В приведенном выше примере, если переменная name имеет значение null или
undefined , то в переменную username будет записано значение по умолчанию 'Guest' .
let age = 0;
let userAge = age ?? 25;
console.log(userAge); // 0
В этом примере переменная age имеет значение 0 , которое является ненулевым (не
null или undefined), поэтому в переменную userAge будет записано это значение, а не
25.
let a = 5;
a++; // a теперь равно 6
let a = 5;
a--; // a теперь равно 4
let a = 5;
console.log(a++); // 5 - ПОСТфиксный
1.3. Операторы 8
console.log(a); // 6
let b = 5;
console.log(++b); // 6 - ПРЕфиксный
console.log(b); // 6
let appleСost = 1;
let watermelonСost = 3;
console.log(appleСost + watermelonСost); //4
1.3. Операторы 9
Про неявное и явное преобразование типов
в JS
JS имеет неявные и явные преобразования типов.
2. Явные преобразования: нужно явно указать, как должен быть преобразован тип.
Это можно сделать с помощью функций parseInt() или Number() и т.д.
Boolean: !!x
String: x.toString()
1.3. Операторы 10
Задания
1. Написать 3 любых примера с % и результат этого выражения (5%2 === 1).
2. Если переменная test равна true, то выведи “Верно”, иначе выведи “Неверно”.
3. Если переменная test не равна true, то выведи “Верно”, иначе выведи “Неверно”.
4. Если переменная a больше нуля и меньше 5-ти, то выведи “Верно“, иначе выведи
“Неверно“.
5. Если переменная a равна нулю или равна двум, то прибавь к ней 7, иначе
раздели ее на 3.
7. Если переменная a больше 2-х и меньше 11-ти, или переменная b больше или
равна 6-ти и меньше 14-ти, то выведи “Верно”, в противном случае выведите
“Неверно”.
let num = 5;
console.log(num == "5"); //?
console.log(num === "5"); //?
console.log(num == true); //?!
1.3. Операторы 11
let count = 6;
console.log(count++); //?
console.log(++count); //?
console.log(count++); //?
console.log(count); //?
let count = 4;
console.log(count--); //?
console.log(count--); //?
console.log(count); //?
console.log(--count); //?
Помоги сделать эту эту главу лучше! Дай обратную связь, а мы прислушаемся к
ней и сделаем ЛУЧШИЙ учебник по JavaScript для тебя и остальных студентов!
Заполни форму
https://forms.gle/APa3mEA8Gq8dFJov9
1.3. Операторы 12
📓
1.4. Циклы и Switch
Циклы
Цикл в JavaScript - это конструкция, которая позволяет повторять определенный
блок кода несколько раз. Он полезен, когда тебе нужно выполнить однотипные
задачи многократно или обработать множество данных.
while
do while
for
let i = 1;
while (i <= 5) {
console.log(i);
i++;
}
let number = 5;
let factorial = 1;
do {
factorial *= number;
number--;
} while (number > 0);
console.log('Факториал числа 5 равен', factorial);
for
Собственно, это совершенно не важно, ибо циклы в чиcтом виде сейчас не
используются совершенно. Они нужны для понимания методов массива. Поэтому
запоминаем и разбираемся именно в цикле for. На него максимальный фокус.
// так лучше
for (let i = 1; i<=3; i++){
console.log("Hello world"+i);
}
Пока блок условие будет true, цикл будет выполняться. Как только блок условие
начало → условие → тело → шаг →условие … и до тех пор пока условие true
Важно еще знать, что такое итерация.
шаг .
Итерация - это процесс, в котором код выполняется несколько раз для решения
какой-либо задачи. Цикл for - это один из способов реализации итерации в
JavaScript.
В цикле for можно указать условие для количества итераций, которые должны
произойти. Например, можно написать цикл for для вывода чисел от 1 до 5:
// Выведет:
// 1
// 2
// 3
// 4
// 5
Break и continue
break и continue- это две ключевые команды, которые можно использовать внутри
цикла for для управления его поведением.
break- это команда, которая прерывает цикл for в любой момент, когда она
выполняется. Например, мы можем использовать break для прерывания цикла,
когда достигается определенное условие:
// Вывод:
// 1
// 2
// Вывод:
// 1
// 3
// 5
Про эти 2 ключевых слова знать не обязательно, ибо все равно не будешь
это использовать на практике никогда
Switch
Switch в JavaScript используется для выполнения различных действий в
зависимости от значения выражения. Это позволяет удобно заменить
последовательность if-else-операторов, когда нам нужно сравнить одно значение с
различными вариантами.
switch (expression) {
case value1:
//Здесь выполняются инструкции, если результат выражения равен value1
break;
case value2:
//Инструкции, соответствующие value2
break;
...
const a = 1;
const b = 2;
switch (a+b) {
case 1:
console.log("Один")
break;
case 3:
console.log("Три")
break;
case 5:
console.log("Пять")
break;
default:
console.log("Ничего не совпало")
}
Так как break нет, JavaScript пойдет выполнять код дальше, !!без каких-либо
проверок!! до следующего break (либо до конца кода switch).
switch (a) {
case 1:
console.log("Один")
case 3:
console.log("Три")
break;
case 5:
console.log("Пять")
break;
default:
console.log("Ничего не совпало")
}
switch (str) {
case 1:
console.log("Один")
case 3:
console.log("Три")
break;
default:
console.log("Ничего не совпало")
}
Тут выведет в консоль "Ничего не совпало", потому что str не совпало ни с одним
значением в case.
Как так? Ведь у нас есть case 3!!
Тут все просто: у них разные типы данных, а switch сравнивает СТРОГО (то
есть учитывает типы данных).
Задания
1. Выведи в консоль числа от 1 до 100.
5 x 1 = 5
5 x 2 = 10
…
5 x 10 = 50
ничего из перечисленого .
🏆 1.5. Функции
1. Берем сковороду.
2. Ставим на плиту.
3. Включаем плиту.
4. Подходим к холодильнику.
5. Открываем холодильник.
6. Берем яичко 🥚
7. Закрываем холодильник.
8. Подходим к плите.
9. Разбиваем яичко.
10. Ждемс 🤤
Описание приготовления яичка условное, но в целом алгоритм может быть описан именно
так. Теперь, когда вам нужно будет в коде описывать приготовление яичка, вам придется
описывать весь этот алгоритм из «10 строк кода». Чтобы этого не делать, можно поступить
проще — оформить все эти действия в функцию “cookEggs” и вызывать ее, когда это
будет нужно.
Мы выяснили, что функция в программировании — это возможность вызвать алгоритм
каких-то действий. То есть функция “cookEggs” — это возможность вызвать алгоритм
1.5. Функции 1
«приготовления яичка», который состоит из множества действий.
Именование функций
В JavaScript функции должны именоваться с использованием CamelCase. То есть все
слова в имени функции должны начинаться с заглавной буквы, кроме первого слова.
Например:
function calculateSum(a, b) {
return a + b;
}
function getUserName() {
return "Павел Гуцу";
}
function createList() {
// твой код
}
create - используется для функций, создающих новый объект или структуру данных,
например, createList ;
… и таких много.
1.5. Функции 2
Виды функций
Есть 3 вида функций:
Function Declaration
Function Expression
Arrow Function
function имяФункции(параметры){
тело функции
}
function sum(a,b){
return a+b;
}
Если мы запустим такой код, он не отработает, потому что функцию нужно вызвать, чтобы
она выполнила свое тело и вернула результат.
function sum(a,b){
return a+b;
}
sum(2,3);//5
sum(3,3);//6
sum(0,6);//6
sum(-10,15);//5
В качестве аргумента функции можно передавать все что угодно, не только числа;
1.5. Функции 3
func(1);//number
func("Redev");//string
func(true);//boolean
func(null);//null
func({name:"Pasha"});//object
func([1,2,3]);//array
func(abc);//function
Работает FE почти так же, как и FD, но есть одно отличие в Hoisting-e.
Функцию, объявленную как FD, можно вызвать до ее объявления! Вот пример
console.log(sumFD(1,2)) //3
function sumFD(a,b){ //FD
return a+b;
}
1.5. Функции 4
Существует короткая запись Arrow Function. В короткой записи не нужно писать слово
⇒
return , так как стрелка ( ) выполняет роль return. Оба варианта работают одинаково.
Сравни
Возврат из функции
return - вот что поможет вернуть результат функции.
Надо запомнить, что функция без return ничего не возвращает, то есть undefined.
Сравни
function sum1(a,b){
const result = a+b;
return result;
}
function sum2(a,b){
const result = a+b;
}
1.5. Функции 5
const sum1 = (a,b) =>{
return a+b;
}
const sum2 = (a,b) =>{
a+b;
}
const sum3 = (a,b) => a+b;
const sum4 = (a,b) => {a+b};
console.log(sum1(2,3));// 5
console.log(sum2(2,3));// undefined
console.log(sum3(2,3));// 5
console.log(sum4(2,3));// undefined
1) login("[email protected]", "verystrongpassword");
2) login("[email protected]");
3) login();
1.5. Функции 6
function showVariable() {
let internalVariable = 5;
console.log(externalVariable);
console.log(internalVariable);
}
showVariable(); // 10, 5
console.log(internalVariable);// ReferenceError: internalVariable is not defined
Задания
1. Напиши функцию, которая определяет, является ли число положительным,
отрицательным или равным нулю.
5. Напиши функцию, которая принимает на вход два числа и выводит в консоль их сумму,
если они оба положительны, и их разность, если одно из чисел отрицательное.
7. Напиши функцию, которая принимает на вход число и выводит на экран его квадрат,
если оно больше 10, и его куб, если оно меньше или равно 10.
8. Напиши функцию, которая принимает на вход два числа и выводит на экран их сумму,
если оба числа положительны, и их произведение, если одно или оба числа
отрицательные.
Помоги сделать эту эту главу лучше! Дай обратную связь, а мы прислушаемся к ней
и сделаем ЛУЧШИЙ учебник по JavaScript для тебя и остальных студентов!
Заполни форму
https://forms.gle/sGRDJSTkJYNXuXsu7
1.5. Функции 7
🕣
2.1. Числа
Number в JavaScript - это тип данных, который используется для хранения
числовых значений.
const num = 5;
const negativeNumber = -5
const decimal = 0.15 // или .15 (результат одинаковый)
Специальные значения
В JavaScript есть три специальных значения. Эти значения принадлежат
типу number , но не работают как обычные числа:
бесконечность Infinity ;
2.1. Числа 1
Значение NaN “прилипчиво”. Любая операция с NaN возвращает NaN:
console.log(5/0); //Infinity
console.log(-5/0) //-Infinity
console.log("Redev"/4) //NaN
отрицательного) ;
undefined) ;
console.log(Number.isNaN(result))// true
console.log(Number.isNaN(result2))// false
const a = Infinity
const b = NaN
const c = 100
console.log(Number.isFinite(a)) // false
2.1. Числа 2
console.log(Number.isFinite(b)) // false
console.log(Number.isFinite(c)) // true
parseInt()
Функция parseInt(string, radix) анализирует строку и возвращает целое число
согласно указанной системе счисления. radix - это система счисления. Если не
указать ее, по умолчанию будет десятичная (почти всегда).
parseInt(string, radix);
parseInt("123asd"); //123
parseInt("qwe123asd"); //NaN
parseInt("asd123"); //NaN
parseInt("12 3asd"); //12
parseInt(" 123asd"); //123
parseInt("3e6"); //3
То есть:
Есть еще метод parseFloat , если хочешь, можешь про него почитать тут
Math
Math - это встроенный объект, который содержит свойства и методы для работы с
математическими константами и функциями.
Более подробно можешь ознакомиться в документации, но ниже я вынес основное
2.1. Числа 3
Число ПИ. примерно 3.14159 .
Math.max()
console.log(Math.PI); //3.141592653589793
BigInt
BigInt - это числовые значения, которые слишком большие для представления в
виде примитивного типа number.
Создается с помощью добавления n в конец целочисленного литерала или
вызовом функции BigInt() и присвоением ей целочисленного или строкового
значения.
const a = 123n;
const b = BigInt(123123123123123) // 123123123123123n
console.log(typeof a) // "bigint"
2.1. Числа 4
В Redev мы не уделяем этой теме времени. Если хочешь, можно почитать
документацию
Задания
1. Какой будет результат?
parseInt('17px'); // ?
parseInt('17px10'); // ?
parseInt('pas123'); // ?
parseInt(' 123px'); // ?
parseInt('6e6'); // ?
2.1. Числа 5
🌙
2.2. Строки
Любые текстовые данные в JavaScript — это строки (англ. string)
Кавычки
В JavaScript есть разные типы кавычек.
Важно помнить, что все типы кавычек должны быть парными, т.е. закрывающие
кавычки должны соответствовать открывающим.
Обратные кавычки могут занимать более одной строки.
2.2. Строки 1
Можно использовать один тип кавычек внутри строки, с объявленой другим типом.
Двойные в одинарных или одинарные в двойных.
Длина строки
Свойство length содержит длину строки. Через него можно узнать количество
символов с строке.
Обращаю внимание, что length является свойством строки, а не методом, так что
тебе не нужно использовать скобки после него.
Доступ к символам
Отдельный символ строки можно получить по порядковому номеру символа в
строке, нумерация которого начинается с 0:
console.log(course[0]) // "R"
console.log(course[2]) // "d"
2.2. Строки 2
console.log(course.at(0)) // "R"
console.log(course.at(-3)) // "d"
означает последний символ, а .at(-2) - символ, который идет перед ним и так
далее.
Квадратные скобки всегда возвращают undefined для отрицательных индексов.
Методы строк
Все методы ты можешь посмотреть в таблице документации.
.toUpperCase()
.toLowerCase()
.indexOf() / .includes()
.slice()
.substring()
.trim()
.repeat()
.toUpperCase() / .toLowerCase()
Метод .toUpperCase() возвращает копию строки, в которой все символы
преобразованы в верхний регистр, а .toLowerCase() соответственно в нижний;
2.2. Строки 3
const course = 'Redev';
console.log(course.toUpperCase()) // "REDEV"
console.log(course.toLowerCase()) // "redev"
.indexOf() / .includes()
и .includes() - это методы строк в JavaScript, которые используются для
.indexOf()
2.2. Строки 4
В приведенном выше примере, position установлен в 1, так что поиск подстроки
"Hello" начинается с позиции 1, и поэтому методы возвращают false или -1 .
.slice()
Он используется для извлечения части строки. Он принимает два аргумента:
начальный индекс и конечный индекс (опциональный).
В этом примере slice вырезает часть строки, начиная с 7-го индекса и заканчивая
12-м (не включая его). Таким образом, извлекается слово "world".
console.log(course.slice(1,3)) // "ed"
console.log(course.slice(2,7)) // "dev C"
console.log(course.slice(6)) // "Courses"
2.2. Строки 5
.substring()
Это метод строк в JavaScript, который используется для извлечения подстроки из
строки. Он принимает два аргумента: начальную и конечную позицию для
извлечения подстроки. Начальная позиция включается в извлекаемую подстроку,
а конечная - нет.
console.log(course.substring(1,3)) // "ed"
console.log(course.substring(3,1)) // "ed" *
console.log(course.substring(2,7)) // "dev C"
console.log(course.substring(6)) // "Courses"
Как мы видим практически тоже самое что и .slice(), но разница есть, и вот какая:
.trim()
Метод убирает лишние пробелы с начала и с конца строки.
2.2. Строки 6
пробелов в начале или конце строки, введенных пользователем.
.repeat()
.repeat() - это метод строк в JavaScript, который возвращает новую строку,
состоящую из повторения исходной строки заданное количество раз. Например:
Сравнение строк
Строки в JavaScript сравниваются по их Unicode-кодам. Это означает, что строки
сравниваются посимвольно, начиная с первых символов. Если символы равны,
то сравниваются следующие символы, и так далее, пока не будет найдено отличие
или до конца строк.
”b” - 62
”c” - 63
…..
и так каждый символ.
2.2. Строки 7
Вот тут можно посмотреть коды для алфавита https://unicode-table.com/ru/
Соотвественно “а” < “b” (тоже самое что и 61 < 62) - и это true
Задачи
1. Напиши функцию, которая ищет индекс первого вхождения заданной
подстроки в строку и возвращает его.
2.2. Строки 8
остальных студентов!
Заполни форму
https://forms.gle/LQGhforDLrE5FDxB8
2.2. Строки 9
🚥
2.3. Объекты. Основы
Объект - это структура данных, которая позволяет хранить множество свойств.
Свойство - это пара "ключ-значение". Ключи могут быть строками или
символами, а значения могут быть любым типом данных, включая другие
объекты.
Пример:
const person = {
fullName: "Pavel Hutsu",
age: 25,
address: {
street: "Bratskaya",
city: "Minsk",
},
};
Доступ к свойствам
В JavaScript есть несколько способов получить доступ к свойствам объекта:
person.age = 26;
console.log(person.age); //26
person["age"] = 27;
console.log(person.age); //27
Удаление свойства
delete - это оператор, который удаляет свойство в объекте.
Например, есть объект person:
delete person.hands;
console.log(person); // {fullName: "Pavel Hutsu"
где key- имя переменной, которая будет принимать значения ключей объекта, а
object - объект, который нужно перебрать.
В результате выполнения этого кода будут выведены все свойства объекта person
и их значения.
Хранение объекта
Надо принять и понять, что в примере выше у нас один объект и 2 переменных,
через которые мы можем “достучаться” к объекту! То есть как мы видим, изменяя
свойство одной переменной, во второй оно тоже изменится. ПОТОМУ ЧТО ОДИН
ОБЪЕКТ!
3. Через JSON.parse/JSON.stringify:
4. structuredClone()
const person = {
name: "Pavel",
age: 25,
address: {
street: "Bratskaya",
city: "Minsk",
zip: "222842"
},
hobbies: ["coding", "coding", "coding"]
};
Если ты хочешь создать копию этого объекта, чтобы изменения в копии не влияли
на оригинальный объект, ты можешь использовать spread оператор (…):
copy.address.street = "Makarevicha";
Однако, если у person есть вложенные объекты или массивы, они будут
скопированы только по ссылке, а не по значению. Это значит, что если ты
изменишь свойство street в объекте address , это изменение отразится как в
оригинальном объекте, так и в копии.
Чтобы создать глубокую копию объекта, ты можешь использовать метод
structuredClone . Этот метод доступен во всех современных браузерах и может
copy.address.street = "Makarevicha";
console.log(copy.address.street); // "Makarevicha"
console.log(person.address.street); // "Bratskaya"
Синтаксис structuredClone
structuredClone(value)
structuredClone(value, options)
value- это объект, который мы хотим скопировать. Он может быть любого типа,
включая объекты, массивы, примитивы, Map, Set и…
Класс Object
Object - это встроенный класс в JavaScript, который предоставляет методы для
работы с объектами. Он является родительским классом для всех объектов в
JavaScript.
Object.assign(person, age);
console.log(person); // { name: 'Pavel', age: 25 }
const person = {
name: 'Pavel',
age: 25
};
Object.freeze(person);
person.name = 'Alesha'; // не будет работать, т.к. объект заморожен
console.log(person.name); // Pavel
const person = {
name: 'Pavel',
age: 25,
};
свойства объекта.
const person = {
name: 'Pavel',
age: 25,
};
Методы объекта
Метод объекта - это функция, которая является свойством объекта (то есть
функция внутри объекта). Она может вызываться и использоваться только
внутри объекта.
const person = {
name: 'Pavel',
age: 25,
sayHi: function() {
console.log(`Hello`);
},
run: function() {
console.log(`I'm running`);
}
};
person.sayHi(); // `Hello`
person.sayHi = function() {
console.log(`привет!`);
};
person.sayHi(); // `привет!`
В обоих случаях, метод может быть вызван с помощью имени объекта и имени
метода, разделенных точкой ( . ). Как и свойство, только вызвать круглыми
скобками.
Конструктор
Конструктор объектов - это функция, которая используется для создания новых
объектов с определенными свойствами и методами.
console.log(person1.name); // "Pavel"
person2.sayHello(); // "Hello, my name is Nastassia"
console.log(user1); // undefined
console.log(user2); // {}
Задачи
1. Напиши функцию, которая принимает объект и возвращает массив его ключей.
11. Создай объект car с методами start и stop , которые выводят в консоль
сообщения "Starting the car" и "Stopping the car" соответственно. Добавь
свойство isRunning , которое будет устанавливаться в true при вызове метода
start ив false при вызове метода stop .
12. Создай объект book с методами open и close , которые выводят в консоль
сообщения "Opening the book" и "Closing the book" соответственно. Добавь
свойство currentPage , которое будет хранить текущую страницу, на которой
находится пользователь. Добавь метод turnPage , который увеличивает
currentPage на 1 и выводит в консоль сообщение "Turning page {page}", где
const person = {
fullName: "Pavel Hutsu",
age: 25,
address: {
street: "Bratskaya",
city: "Minsk",
},
};
Теперь, если мы изменим исходный объект person , например, изменив его возраст,
то это изменение не влияет на клон:
person.age = 40;
console.log(personClone.age); // 30
const person = {
fullName: "Pavel Hutsu",
age: 25,
address: {
street: "Bratskaya",
city: "Minsk",
},
};
person.address.city = 'Brest';
console.log(personClone.address.city); // Brest
console.log(person.address.city); // Brest
const person = {
name: 'Pavel',
age: 25,
sayHi: function() {
console.log(`Привет, меня зовут ${this.name}`);
}
};
В этом примере, this указывает на объект person , и при вызове метода sayHi мы
можем достучаться до его свойства name с помощью this.name .
function greet() {
console.log(this); // global
console.log(`Hello, my name is ${this.name}`);
}
const person = {
name: 'Pavel',
age: 25,
};
person.sayHi = function () {
console.log(`Привет, меня зовут ${this.name}`);
}
person.sayHi(); // `Привет, меня зовут Pavel`
const person = {
name: 'Pavel',
age: 25,
};
function sayHi() {
console.log(`Привет, меня зовут ${this.name}`);
}
person.sayHi = sayHi;
const person = {
name: 'Pavel',
person.sayHi = sayHi;
Видишь, разницы нет. Просто ты теперь знаешь, что можно и так и так
const obj = {
myProperty: 42,
myMethod: () => {
console.log(this.myProperty);
}
}
obj.myMethod(); // undefined
установлено для this внутри функции, где она была объявлена. Это делает
работу со стрелочными функциями более предсказуемой и удобной, но требует
внимательного отношения к контексту, в котором они используются.
const obj = {
myProperty: 42,
myMethod: () => this.myProperty,
myMethod2: function () {
console.log(obj.myMethod()); // undefined
console.log(obj.myMethod2()); // 42
Еще можно запомнить это как “this в стрелочной функции берется извне. Там где
она объявлена, а не вызывается! ”
В коде ниже это сразу видно:
const obj = {
myProperty: 42,
myMethod: () => this.myProperty,
myMethod2: function () {
const fn = () => this.myProperty;
return fn()
},
myMethod3: function () {
return fn3()
}
}
console.log(obj.myMethod()); // undefined
console.log(obj.myMethod2()); // 42
console.log(obj.myMethod3()); // undefined
function greet(greeting) {
console.log(`${greeting}, my name is ${this.name}`);
}
const person = {
name: 'Pavel'
};
function greet(greeting) {
console.log(`${greeting}, my name is ${this.name}`);
}
const person = {
name: 'Pavel'
};
function greet() {
console.log(`Hello, my name is ${this.name}`);
}
const person = {
name: 'Pavel'
};
Задачи
1. Создай объект person с свойством name и методом greet , который выводит в
консоль строку "Hello, my name is {name}". Используй this внутри метода
greet для получения значения свойства name объекта person .
4. Создай объект game с методом play , который выводит в консоль "Playing {title}
game". Используй метод call или apply , чтобы вызвать метод play с
объектами basketballGame и chessGame , имеющими свойства title , которые
представляют соответствующие игры.
https://forms.gle/k2uKurkpeJgUXhub8
🛎 3.1. Массивы
Создание массива
3.1. Массивы 1
Есть несколько способов создать массив. Легче всего создать массив используя
квадратные скобки и разделяя элементы запятой. Элементы массива могут быть
любым выражением, в том числе объектами.
3. Явно указать в вызове конструктора значения первых двух или более элементов
массива или один нечисловой элемент:
3.1. Массивы 2
Про длину (.length)
Длина массива - это количество элементов в массиве*. Для получения длины
массива в используется свойство .length , которое является числовым значением,
равным количеству элементов в массиве.
Например, чтобы узнать длину массива arr , можно использовать следующий код:
3.1. Массивы 3
индекс 1 и т.д.
Чтобы получить доступ к элементу массива, нужно указать имя массива и индекс
элемента в квадратных скобках, например:
myArray[0] = 'банан';
console.log(myArray); // выведет ['банан', 'апельсин', 'груша']
console.log(myArray.length); // 4
Как мы видим длина станет 4. Почему так? Ведь выше говорили, что .length - это
количество элементов в массиве. Да, это так, но давай чуть-чуть уточним. На
самом же деле .length это СТАРШИЙ ИНДЕКС +1.
3.1. Массивы 4
Сейчас поясню.
Какой СТАРШИЙ индекс есть у myArray? Конечно же 3. Мы его сами задали и
присвоили элементу - банан . Соответственно старший индекс + 1 это 3 + 1 = 4;
myArray.length = 2;
console.log(myArray, myArray.length); // [3,5], 2
Оператор delete
Оператор delete как и с объектами, может удалить элемент массива. Он удаляет
элемент из массива, но не изменяет индексы массива и не сокращает его длину.
3.1. Массивы 5
Перебор массива
1. Перебор массива с помощью цикла for. Для этого используется следующий
синтаксис:
Также можно использовать цикл for для изменения каждого элемента массива.
Например, мы можем увеличить каждый элемент массива на 1 с помощью
следующего кода:
console.log(arr); // [2, 3, 4, 5, 6]
3.1. Массивы 6
for (const value of array) {
// блок кода
}
console.log(sum); // 15
Array.isArray()
Метод Array.isArray() используется для проверки, является ли переданный
аргумент массивом или нет. Он возвращает булево значение - true , если аргумент
является массивом, и false , если нет.
Array.isArray(value)
3.1. Массивы 7
const obj = {name:"Pavel"};
console.log(Array.isArray(obj)); // false
Задания
1. Напиши функцию, которая принимает массив и возвращает сумму четных
элементов в массиве чисел.
https://forms.gle/TWcTStGQXfpc78RZ9
3.1. Массивы 8
🏕
3.2. Методы массивов
Список всех
Наивысший приоритет
1. forEach() - выполняет указанную функцию один раз для каждого элемента
массива.
возвращает false.
Низкий приоритет
forEach()
Метод массива forEach() выполняет заданную функцию один раз для каждого
элемента массива без необходимости явного использования цикла for или while .
console.log(result); // undefined
// Вывод в консоль
// 1
// 2
// 3
map()
Метод массива map() является одним из наиболее полезных методов. Он
позволяет применять функцию к каждому элементу массива и возвращать новый
массив с результатами. Это очень мощный инструмент, который может быть
использован для трансформации данных и упрощения кода.
Вот пример использования метода map() для удвоения всех элементов массива:
В этом примере метод map() создает новый массив doubledArr , который содержит
результат удвоения каждого элемента исходного массива arr . Функция обратного
вызова, переданная в метод map() , просто умножает каждый элемент на 2 и
возвращает новое значение.
map() может быть использован для выполнения любых операций, которые можно
выполнить с каждым элементом массива. Он также может быть использован для
filter()
Метод массива filter() используется для создания нового массива из исходного
массива, содержащего только те элементы, которые удовлетворяют условие
заданном в callback-функции.
Функция обратного вызова должна вернуть булево значение true или false ,
чтобы указать, должен ли элемент быть включен в новый массив.
find()
Метод find() возвращает первый элемент массива, который удовлетворяет
условию, заданному в переданной ему callback-функции. Если в массиве не
найден ни один элемент, удовлетворяющий условию, метод find() возвращает
undefined .
где:
sort()
Метод sort() позволяет сортировать элементы массива и изменять порядок их
расположения. Метод сортирует элементы массива на месте, то есть не создает
новый отсортированный массив, а изменяет порядок элементов в исходном
массиве.
Синтаксис метода:
array.sort([compareFunction])
Примеры:
1. Сортировка чисел:
2. Сортировка строк:
3. Сортировка объектов:
const students = [
{ name: 'Pavel', grade: 8 },
{ name: 'Roma', grade: 7 },
{ name: 'Katya', grade: 9 },
];
reduce()
Метод reduce() используется для преобразования массива в единое значение
(число, строку, объект и т.д.), путем применения функции к каждому элементу
массива и аккумуляции результата (накопления).
console.log(sum); // 15
console.log(result); // "12345"
indexOf()
Метод массива indexOf() возвращает индекс первого вхождения заданного
элемента в массиве или -1, если элемент не найден.
Синтаксис метода:
arr.indexOf(searchElement[, fromIndex])
где:
Примеры использования:
console.log(fruits.indexOf('banana')); // 1
console.log(fruits.indexOf('pear', 2)); // 3
console.log(fruits.indexOf('grape')); // -1
includes()
Метод массива includes() - это метод JavaScript, который используется для
определения, содержит ли массив определенный элемент, и возвращает
логическое значение true или false.
Синтаксис метода includes():
array.includes(searchElement, fromIndex)
Метод includes() также может использоваться для поиска строк в массивах строк:
splice()
Метод splice() позволяет изменять содержимое массива путем удаления или
замены существующих элементов и/или добавления новых элементов.
Параметры:
// заменить два элемента начиная с индекса 1 (banana и cherry) на элементы "lemon" и "lim
e"
fruits.splice(1, 2, "lemon", "lime");
join()
Метод join() используется для объединения всех элементов массива в одну
строку.
Синтаксис метода выглядит следующим образом:
reverse()
Метод reverse() изменяет порядок элементов в массиве на обратный. Это
означает, что первый элемент становится последним, второй - предпоследним и
так далее, а последний элемент становится первым.
array.reverse();
fill()
Метод fill() массива в JavaScript используется для заполнения всех элементов
массива одним и тем же значением. Он изменяет исходный массив, а не создает
новый массив.
Здесь метод fill() заполняет два последних элемента массива arr4 значением 0,
начиная с индекса -2 (предпоследнего элемента массива).
push()
Метод push() - позволяет добавлять один или несколько элементов в конец
массива. Синтаксис метода push() выглядит следующим образом:
Здесь array - это массив, в который нужно добавить элементы, а element1, ...,
elementN - это элементы, которые нужно добавить. Метод push() изменяет
Например:
shift()
shift() - это метод массива в JavaScript, который удаляет первый элемент из
массива и возвращает его значение. Если массив пустой, то метод shift() вернет
undefined . Метод shift() также изменяет длину массива, удаляя первый элемент
из массива.
unshift()
Метод unshift() используется для добавления одного или нескольких элементов в
начало массива.
Синтаксис метода unshift() выглядит следующим образом:
flat()
Метод flat() создает новый массив, в котором все подмассивы в исходном
массиве выровнены в один уровень глубины. То есть, если исходный массив
содержит вложенные массивы, метод flat() "разворачивает" их, превращая
многомерный массив в одномерный.
every()
Метод every() принимает callback-функцию и проверяет, удовлетворяет ли
каждый элемент массива условию, заданному этой функцией. Если каждый
элемент массива удовлетворяет этому условию, то метод возвращает true . Если
хотя бы один элемент не удовлетворяет условию, то метод возвращает false .
arr.every(callback[, thisArg])
Здесь arr - это массив, на котором вызывается метод every() , callback - это
функция обратного вызова, которая будет вызвана для каждого элемента массива,
и thisArg - это значение, которое будет использовано в качестве this при вызове
функции callback .
Функция callback принимает три аргумента: item , index и array . item - это
текущий элемент массива, index - это индекс текущего элемента, а array - это сам
массив, на котором вызывается метод every() .
Вот несколько примеров использования метода every() :
В первом примере метод every() возвращает true , потому что все элементы
массива arr1 больше 0. Во втором примере метод every() возвращает false ,
потому что один из элементов массива arr2 (число 7) не является четным.
some()
Метод some() используется для проверки того, соответствует ли хотя бы один
элемент массива заданному условию. Метод возвращает булевое значение true ,
если условие истинно для хотя бы одного элемента массива, и false , если это не
так.
Синтаксис метода some() выглядит следующим образом:
array.some(callback[, thisArg])
Функция callback принимает три аргумента: item , index и array . item - это
текущий элемент массива, index - это индекс текущего элемента, а array - это сам
массив, на котором вызывается метод every() .
Метод some() особенно полезен при работе с большими массивами, когда нужно
быстро определить, есть ли в них элементы, удовлетворяющие заданному
условию.
concat()
Метод concat() в JavaScript используется для объединения двух или более
массивов в один новый массив. Он не изменяет исходные массивы, а возвращает
новый массив, содержащий все элементы исходных массивов в порядке их
следования.
Синтаксис метода concat() выглядит следующим образом:
где array1 - массив, в который будут добавлены другие массивы, array2 , array3 ,
..., arrayN - массивы, которые нужно добавить в array1 . Метод concat() может
принимать любое количество аргументов массивов.
slice()
Метод массива slice() используется для создания нового массива, содержащего
выбранные элементы из исходного массива. Он не изменяет исходный массив,
а возвращает новый массив, который может быть сохранен в переменной или
использован для дальнейшей обработки.
arr.slice(start, end);
Если start больше, чем индекс последнего элемента в массиве, то slice() вернет
пустой массив. Если end меньше, чем start , то также будет возвращен пустой
массив.
Метод slice() также может использоваться для создания копии массива. Для
этого достаточно вызвать slice() без аргументов:
Заметим, что копия массива создается поверхностно, т.е. если исходный массив
содержит объекты, то в новом массиве будут храниться ссылки на эти объекты, а
не их копии.
Доп.
8 методов которые изменяют исходный массив.
Задания
1. Напиши функцию, которая принимает массив строк и возвращает новый
массив, в котором каждая строка записана в верхнем регистре.
const people = [
{ name: 'Pavel', age: 25 },
{ name: 'Alex', age: 20 },
{ name: 'Irina', age: 30 },
];
13. Напиши функцию, которая принимает массив чисел и разделяет массив на две
группы: четные и нечетные {even:[], odd:[]} (через reduce)
☔ 4.1. ДП + spread
Деструктуризация массива
Деструктуризация массива - это процесс извлечения значений из массива и
присваивания их переменным.
Пример:
console.log(a); // 1
console.log(b); // 2
console.log(c); // 3
Rest (…) - это оператор, который позволяет нам собрать все оставшиеся
элементы массива в одну переменную.
Пример использования rest:
console.log(a); // 1
4.1. ДП + spread 1
console.log(b); // 2
console.log(rest); // [3, 4, 5]
console.log(a); // 1
console.log(b); // 2
console.log(ostatok); // [3, 4, 5]
console.log(a); // 1
console.log(b); // 2
console.log(c); // 3
4.1. ДП + spread 2
два элемента, то переменной c будет присвоено значение по умолчанию. Если
бы значения по умолчанию не было, то c была бы равна undefined .
console.log(a); // 1
console.log(d); // 4
console.log(e); // 5
Деструктуризация объекта
Деструктуризация объекта - это процесс извлечения значений свойств объекта и
присваивания их переменным. Для деструктуризации объекта можно использовать
фигурные скобки, где ключи свойств объекта выступают в качестве имен
переменных, которым будут присвоены соответствующие значения.
Пример деструктуризации объекта:
console.log(name); // "Pavel"
console.log(age); // 25
В этом примере создается объект myObject с двумя свойствами - name и age . Затем
используется деструктуризация объекта, чтобы присвоить значения этих свойств
переменным name и age .
4.1. ДП + spread 3
Кроме того, при деструктуризации объекта можно использовать значение по
умолчанию, которое будет присвоено переменной, если свойство объекта
отсутствует.
console.log(name); // "Pavel"
console.log(age); // 25
console.log(name); // "Pavel"
console.log(rest); // {age: 25, city: "Minsk"}
Пример:
4.1. ДП + spread 4
const myObject = {name: "Pavel", age: 25};
console.log(fullName); // "Pavel"
console.log(userAge); // 25
В этом примере создается объект myObject с двумя свойствами - name и age . Затем
используется деструктуризация объекта, чтобы присвоить значения свойств
объекта переменным fullName и userAge , переименовав при этом свойства
объекта.
Таким образом, свойство name объекта myObject было переименовано в
переменную fullName , а свойство age - в переменную userAge .
Деструктуризация строки
Деструктуризация строки - это процесс извлечения отдельных символов или
подстрок из строки в JavaScript.
Вот несколько примеров использования деструктуризации строки в JavaScript:
4.1. ДП + spread 5
Деструктуризация может быть полезна в
следующих случаях:
1. Передача параметров в функцию. Деструктуризация может быть
использована для передачи объекта в функцию и извлечения его свойств в
качестве параметров. Это удобно, когда нужно передать только определенные
свойства объекта в функцию.
const user = {
name: "Pavel",
age: 25,
address: {
city: "Minsk'",
4.1. ДП + spread 6
country: "Belarus",
},
};
const person = {
firstName: 'Pavel',
lastName: 'Hutsu'
};
Spread
Оператор spread ( ... ) - это удобный способ для копирования массивов и
объектов, а также для объединения нескольких массивов и объектов в один.
4.1. ДП + spread 7
const arr1 = [1,2,3];
const arr2 = [...arr1];
console.log(arr2); // [1,2,3]
console.log(arr3); // [1,2,3,4,5,6]
console.log(obj2); // {name:"Pavel"}
4.1. ДП + spread 8
В этом примере, obj2 будет содержать все свойства obj1 , но со значением
свойства age , измененным на 26 .
Задания
Задания для закрепления темы деструктуризации с массивами:
4.1. ДП + spread 9
4. Создай объект myObject с полями name , age , city и country . Используя
деструктуризацию, присвой значения полям name , age и city переменным
https://forms.gle/52fk9GAbrdQDrNd49
🧵 4.2. JSON
4.1. ДП + spread 10
🧵
4.2. JSON
JSON (JavaScript Object Notation) - это легкий формат обмена данными, который
используется для передачи и хранения структурированных данных между
клиентом и сервером.
В JavaScript, данные могут быть представлены в виде объектов и массивов. JSON
использует синтаксис, который очень похож на синтаксис объектов и массивов в
JavaScript, но существуют некоторые отличия.
JSON имеет следующие особенности:
JSON представляет данные в виде пар “ключ-значение”, где ключ - это строка
(а не строка и символ, как в объекте), а значение может быть любого типа,
включая объекты и массивы.
В JavaScript для работы с JSON используется объект JSON , который содержит два
метода:
JSON.stringify()
Метод JSON.stringify() является одним из методов объекта JSON в JavaScript,
который преобразует объект JavaScript в строку JSON.
Синтаксис метода:
4.2. JSON 1
value - это значение, которое нужно преобразовать в строку JSON.
replacer- это опциональный (необязательный) параметр, который позволяет
указать функцию, которая будет вызываться для каждого элемента объекта во
время преобразования. Функция получает два параметра: ключ и значение
текущего элемента объекта. Если функция возвращает undefined , элемент не
включается в результирующую JSON-строку. Если replacer является массивом, то
он должен содержать список свойств, которые нужно сериализовать.
space - опциональный параметр, который определяет количество пробелов или
символов табуляции для отступа в создаваемой строке JSON.
const user = {
name: 'Pavel',
age: 25,
isAdmin: true,
hobbies: ['eating', 'sleeping']
};
`{"name":"Pavel","age":25,"isAdmin":true,"hobbies":["eating","sleeping"]}`
Затем мы можем использовать метод JSON.parse() (подробнее про него ниже) для
преобразования этой строки JSON обратно в объект JavaScript:
4.2. JSON 2
const jsonObject = JSON.parse(jsonString);
console.log(jsonObject);
{
name: 'Pavel',
age: 25,
isAdmin: true,
hobbies: ['eating', 'sleeping']
}
const data = {
name: "Pavel",
age: 25,
hobbies: ['eating', 'sleeping'],
address: {
street: "Bratskaya",
city: "Minsk",
}
};
console.log(jsonString1);
/*
Вывод:
{
"name": "John",
"age": 30,
"hobbies": [
"reading",
"sports"
]
}
*/
4.2. JSON 3
// использование массива в качестве replacer
const jsonString2 = JSON.stringify(data, ["name", "hobbies"], 4); // используем 4 пробела
для отступов
console.log(jsonString2);
/*
Вывод:
{
"name": "Pavel",
"hobbies": [
"eating",
"sleeping"
]
}
*/
JSON.parse()
- это метод, который позволяет преобразовывать строку JSON в
JSON.parse()
JSON.parse(text[, reviver])
должна быть определена таким образом, чтобы принимать два параметра: ключ и
значение. Она должна возвращать значение, которое будет использоваться в
качестве значения свойства, или undefined , если свойство должно быть удалено.
4.2. JSON 4
Вот пример использования JSON.parse() с функцией reviver :
console.log(obj);
// {name: "Pavel", age: 30, city: "Minsk"}
Задания
1. Напиши функцию, которая принимает на вход JSON-строку с объектом и
возвращает количество свойств в объекте.
4.2. JSON 5
пользователей, у которых более 1000 подписчиков.
https://forms.gle/GWykoZMQXqig6d2w6
⚠ 4.3. try…catch...finally
4.2. JSON 6
⚠
4.3. try…catch ...finally
try...catch...finally является конструкцией языка JavaScript, которая позволяет
обрабатывать ошибки во время выполнения кода.
try {
// код, который может выбросить исключение (ошибку)
} catch(error) {
// обработка ошибки
} finally {
// код, который выполнится всегда
}
4.3. try…catch...finally 1
ошибка или нет.
try {
const a = 10;
console.log(a+b); // тут ошибка, нет переменной b
} catch (error) {
console.log("Ошибка: " + error.message); // Ошибка: b is not defined
} finally{
console.log("сюда код дойдет");
}
console.log("и сюда код тоже дойдет");
const a = 10;
console.log(a+b); // тут ошибка, нет переменной b
error
- это объект ошибки, который содержит информацию о типе ошибки и другие
error
try {
const result = someFunction(2); // вызов функции, которая может вызвать ошибку
console.log(result); // если ошибки не возникло, выводим результат
} catch (error) {
console.log("Ошибка: " + error.message); // Ошибка: b is not defined
}
4.3. try…catch...finally 2
Свойство message содержит текстовое описание ошибки
try {
// код, который может вызвать ошибку
} catch (error) {
console.log(error.message); // выводим сообщение об ошибке
console.log(error.name); // выводим имя ошибки
console.log(error.stack); // выводим стек вызовов
}
throw
в JavaScript используется для генерации исключений (ошибок). Когда
throw throw
throw выражение;
4.3. try…catch...finally 3
Вот пример использования оператора throw для генерации ошибки:
function divide(x, y) {
if (y === 0) {
throw new Error("Деление на ноль невозможно");
}
return x / y;
}
try {
const result = divide(6, 0);
} catch (error) {
console.log(error.message);
}
Еще пример
Для примера, представь себе, что ты пишешь программу для расчета средней
оценки по математике. Если пользователь вводит отрицательную оценку, это
может привести к ошибке. В таком случае, ты можешь использовать оператор
throw , чтобы выбросить исключение и сообщить пользователю о неправильном
вводе данных.
Например, так можно выбросить исключение:
function calculateAverage(grades) {
if (grades.some(grade => grade < 0)) {
throw "Оценки не могут быть отрицательными!";
}
try {
const result = calculateAverage([4, 5, 3, -2, 6]);
4.3. try…catch...finally 4
console.log(result);
} catch (error) {
console.error(error);
}
Задания
1. Напиши функцию, которая принимает на вход два числа и возвращает их
сумму. В случае, если аргументы не являются числами, функция должна
бросать исключение.
4.3. try…catch...finally 5
обоих аргументов, для третьего задания можно добавить проверку на тип
значений полей x и y , и т.д.
https://forms.gle/Jo85vcDQUbpmqj1c9
🪧 4.4. Прототип
4.3. try…catch...finally 6
🪧
4.4. Прототип
Прототипы - это особенность языка JavaScript, которая позволяет создавать
объекты, унаследованные от других объектов.
Прототип является объектом-предком для другого объекта, и когда свойство или
метод не найден в самом объекте, JavaScript автоматически ищет его в
прототипе.
Это позволяет создавать более эффективный и гибкий код, так как можно
определить общие свойства и методы для группы объектов, а затем использовать
их для каждого объекта в этой группе, без необходимости повторять код для
каждого объекта.
// Создаем объект-родитель
const parent = {
name: "Родитель",
greet: function() {
console.log("Привет, я " + this.name);
}
};
4.4. Прототип 1
В этом примере мы создали объект "родитель" с именем и методом приветствия.
Затем мы создали объект "ребенок", используя метод Object.create() , который
создает новый объект с указанным объектом в качестве прототипа. Затем мы
переопределили имя ребенка и вызвали метод приветствия, который был
унаследован от родителя.
Таким образом, прототипы позволяют нам создавать объекты, которые наследуют
свойства и методы от других объектов, что делает код более модульным и
удобным для работы.
Object.create(proto, propertiesObject);
2. Свойство __ proto __
4.4. Прототип 2
// Создаем объект-родитель
const parent = {
name: "Родитель",
greet: function() {
console.log("Привет, я " + this.name);
}
};
const parent = {
name: "Родитель",
greet: function() {
console.log("Привет, я " + this.name);
}
};
const child = {
name: "Ребенок",
};
child.__proto__ = parent;
4.4. Прототип 3
несовместимо с некоторыми браузерами. Вместо этого
рекомендуется использовать методы Object.getPrototypeOf() и
Object.setPrototypeOf() .
Итого: есть 2 способа задать прототип при создании через Object.create() и через
свойство __ proto __ .
Есть 2 ограничения на прототипы:
Цепочка прототипов
В JavaScript цепочка прототипов отображает наследование свойств и
методов между объектами. Каждый объект имеет внутреннюю ссылку на свой
прототип, который является объектом, от которого он наследует свойства и
методы.
Если свойство или метод не найден в объекте, то поиск происходит в его
прототипе, а затем в прототипе прототипа и так далее до тех пор, пока свойство
или метод не будет найден или не достигнут конец цепочки прототипов.
4.4. Прототип 4
Например, у нас есть объект "dog" с прототипом "animal" , а прототипом "animal"
является объект "livingBeing" . В этом случае цепочка прототипов выглядит
следующим образом:
4.4. Прототип 5
animal.eat = function() {
console.log("Ест");
};
Свойство prototype
В JavaScript, каждая функция является объектом, и у каждой функции есть
свойство prototype , которое представляет прототип этой функции.
Свойство prototype функции является объектом, который используется как
прототип для объектов, создаваемых с помощью этой функции при вызове
оператора new .
Этот объект содержит свойства и методы, которые будут унаследованы
экземплярами, созданными с помощью функции-конструктора.
Для лучшего понимания, давай рассмотрим следующий пример:
Person.prototype.sayHello = function() {
console.log(`Hello, my name is ${this.name} and I'm ${this.age} years old`);
};
4.4. Прототип 6
person1.sayHello(); // выводит "Hello, my name is Alice and I'm 25 years old"
person2.sayHello(); // выводит "Hello, my name is Bob and I'm 30 years old"
функции Person . Это означает, что мы можем вызвать метод sayHello() на обоих
объектах, и метод будет работать корректно.
С помощью prototype в уже существующие объекты можно добавлять новые
методы или создавать полифилы.
4.4. Прототип 7
1. https://habr.com/ru/company/otus/blog/685528/
2. https://habr.com/ru/post/518360/
2. https://habr.com/ru/company/hexlet/blog/260427/
Задания
1. Создать объект с помощью функции-конструктора и добавить ему свойства и
методы через прототип.
const obj = {
a: "AAA",
__proto__: {
a: "BBB",
funcA() {
return this.a;
}
}
}
console.log(obj.funcA());
const obj = {
a: "AAA",
}
const obj2 = {
a: "BBB",
funcA() {
return this.a;
}
}
obj.__proto__ = obj2;
console.log(obj.funcA());
4.4. Прототип 8
5. Написать полифил для метода массива .map.
https://forms.gle/ZtYZNcdVSJZ75Rm58
4.4. Прототип 9
🗓
4.5. Дата и время
В JavaScript существует встроенный объект Date, который позволяет работать с
датами и временем.
Параметры функции new Date(year, month, day, hours, minutes, seconds, ms) задают
год, месяц (от 0 до 11), день, часы, минуты, секунды и миллисекунды
(опционально). Обратите внимание, что месяцы начинаются с 0 (январь), а не с 1
(февраль).
Вот все что ты сейчас прочел надо знать, но для работы с датами и временем в
React/Redux , Node.js и т.д. используется библиотека moment.js
Когда начнешь писать приложения обрати на этой внимание и попробуй ее, а пока
закрепи на практике работу с датой и временем
Задания
1. Напиши функцию, которая будет принимать на вход дату и время и
возвращать ближайшее время в формате "ЧЧ:ММ", кратное 5 минутам.
Например, если на вход подано "17.03.2023 12:13", то функция должна вернуть
"12:10".
Map
Map — это коллекция, которая хранит данные в виде пар ключ-значение. При этом
ключ может быть любого типа (включая объекты и функции), а значение — любого
типа данных (примитивы, объекты и функции). Map сохраняет порядок добавления
элементов, и предоставляет методы для добавления, удаления и получения
элементов по ключу.
new Map() – создаёт коллекцию.
Set
Set — это коллекция, которая хранит набор уникальных значений любого типа
(примитивы, объекты и функции). Set также сохраняет порядок добавления
элементов, и предоставляет методы для добавления, удаления и проверки
наличия элементов.
итерируемый объект (обычно это массив), то копирует его значения в новый Set.
Конечно это не все коллекции. В JS есть еще коллекции, но я не считаю что про
них нужно знать… но если вдруг ты хочешь, то вот ссылка
https://developer.mozilla.org/ru/docs/Web/JavaScript/Guide/Keyed_collections
Задания
1. Напиши функцию countWords(str) , которая принимает на вход строку и
возвращает объект Map, в котором ключами являются слова из строки, а
значениями - количество их вхождений в строку.
Например, для строки "Я люблю маму, а так же я люблю JavaScript" функция должна
вернуть Map со следующими парами ключ-значение: "Я" -> 2 , "люблю" -> 2 ,
"маму" -> 1 , и т.д.
Замыкание
Замыкание (closure) в JavaScript - это функция, которая запоминает переменные
из внешней области видимости (lexical environment), где она была объявлена,
даже после того, как эта область видимости закончила свою работу. Замыкание
формируется при объявлении функции внутри другой функции и
использовании внешних переменных внутри вложенной функции.
function outer() {
let x = 10;
function inner() {
console.log(x);
}
return inner;
}
function createCounter() {
let count = 0;
return function() {
count++;
console.log(count);
}
}
Рекурсия
Рекурсия в JavaScript - это когда функция вызывает саму себя в своем теле. Это
может показаться странным, но это очень мощный инструмент для решения
function countdown(n) {
console.log(n);
if (n > 0) {
countdown(n - 1);
}
}
countdown(5);
Вот еще один пример - функция factorial , которая вычисляет факториал числа:
function factorial(n) {
if (n === 0) {
return 1;
} else {
return n * factorial(n - 1);
}
}
дает значение 1 .
В обоих этих примерах рекурсия позволяет использовать простой код для
решения задач, которые могут быть трудно решить иными способами.
Каррирование
Каррирование - это процесс преобразования функции с несколькими
аргументами в последовательность функций, каждая из которых принимает только
один аргумент.
function add(x, y) {
return x + y;
}
function add(x) {
return function(y) {
return x + y;
}
}
function add(x, y) {
return x + y;
}
console.log(curryAdd(add)(2)(3));
console.log(curriedMultiply(2, 3, 4)); // 24
console.log(curriedMultiply(2)(3, 4)); // 24
console.log(curriedMultiply(2)(3)(4)); // 24
Задания
1. Задание на замыкание: Напиши функцию, которая принимает на вход число,
а затем возвращает другую функцию, которая при каждом вызове будет
возвращать сумму переданного числа и того, что передано при первом вызове.
🏛 5.1. class
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayHello() {
console.log(`Привет, меня зовут ${this.name} и мне ${this.age} лет.`);
}
}
5.1. class 1
Почему если вывести в консоль person из примера выше, то мы не увидим
там методов?
Если мы выведем объект person из примера выше в консоль, то мы действительно
не увидим там методов. Это потому, что методы в JavaScript-классах хранятся в
прототипе объекта, а не в самом объекте.
При создании объекта person на основе класса Person с помощью оператора new ,
в памяти выделяется объект, который содержит все его свойства ( name и age ). Но
метод sayHello , не хранится непосредственно в этом объекте. Вместо этого он
хранится в прототипе объекта.
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
При создании нового объекта на основе класса Person с помощью оператора new ,
конструктор вызывается автоматически:
5.1. class 2
Здесь мы создаем новый объект person на основе класса Person и передаем
значения name и age в конструктор класса. Конструктор класса инициализирует
свойства объекта person , устанавливая значение name в 'John' и age в 30 .
Геттеры и сеттеры
Геттеры и сеттеры в классах — это специальные методы, которые позволяют
получать (get) и устанавливать (set) значения свойств объекта.
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
get age() {
return this._age;
}
set age(value) {
if (value < 0) {
console.log("Возраст не может быть отрицательным");
return;
}
this._age = value;
}
}
5.1. class 3
const person = new Person("Pavel", 25);
console.log(person.age); // 25
person.age = 30;
console.log(person.age); // 30
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
get age() {
return this._age;
}
set age(value) {
if (value < 0) {
console.log("Возраст не может быть отрицательным");
return;
}
this._age = value;
}
}
5.1. class 4
Использование защищенных свойств позволяет скрыть детали реализации класса
и обеспечить его безопасность.
Защищенного свойства на самом деле не существует в стандарте языка. Это
просто договоренность между разработчиками, что свойство с нижним
подчеркиванием мы не будем менять на прямую, а будем использовать геттер и
сеттер.
2. Статические
Статические свойства и методы в JavaScript-классах — это свойства и методы,
которые принадлежат самому классу, а не его экземплярам.
class Person {
static count = 0;
constructor(name, age) {
this.name = name;
this.age = age;
Person.count++;
}
}
console.log(Person.count); // 2
5.1. class 5
Пример статических методов в JS. Math.max() , Math.min() , Promise.all() ,
Promise.resolve() ,…
3. Приватные
Свойства, которые начинаются с символа # в JavaScript называются приватными
свойствами (private fields). Они были добавлены в стандарт ECMAScript 2019 и
позволяют определять свойства, которые могут быть доступны только внутри
класса (обращаются к ним через this), где они были определены.
class Person {
#name;
constructor(name) {
this.#name = name;
}
getName() {
return this.#name;
}
setName(name) {
this.#name = name;
}
}
console.log(person.getName()); // "Pavel"
person.setName("Alina");
console.log(person.getName()); // "Alina"
5.1. class 6
Итого:
Наследование классов
В JavaScript классы наследуются с помощью ключевого слова extends при
определении дочернего класса. Класс-потомок наследует свойства и методы
родительского класса, и может добавлять собственные свойства и методы.
class Person {
constructor(name) {
this.name = name;
}
sayHello() {
console.log(`Привет, меня зовут ${this.name}`);
}
}
introduce() {
console.log(`Привет, меня зовут ${this.name} и я ${this.title}`);
}
}
5.1. class 7
В этом примере мы определили родительский класс Person , который имеет
свойство name и метод sayHello .
Затем мы определили дочерний класс Employee , который наследует свойства и
методы родительского класса с помощью ключевого слова extends и метода
super() .
Класс Employee также имеет свойство title и метод introduce , который выводит
информацию о себе и родительском классе. Создав экземпляр класса Employee ,
мы можем использовать как методы родительского класса Person , так и методы
дочернего класса Employee .
class Person {
constructor(name) {
this.name = name;
}
}
В этом примере будет ошибка. Почему? Потому что в дочернем конструкторе нет
this , и код this.title = title; не отработает.
super
В JavaScript ключевое слово super используется внутри конструктора дочернего
класса для вызова конструктора родительского класса и получения доступа к его
свойствам и методам.
То есть, когда мы вызывали в примере выше super(name) у класса Employee мы
вызывали constructor класса Person . Вот и всë.
5.1. class 8
Так же super можно использовать для вызова метода
class Person {
sayHi() {
return "Hi"
}
}
Вывод:
Переопределение методов
В JavaScript, методы классов могут быть переопределены путем создания нового
метода с тем же именем, что и унаследованный метод. При вызове метода на
экземпляре класса будет вызываться переопределенный метод, а не
унаследованный.
class Animal {
makeSound() {
console.log("Animal is making a sound");
}
}
5.1. class 9
console.log("Woof woof!");
}
}
В этом примере, класс Dog наследует метод makeSound от класса Animal . Однако, в
классе Dog переопределен метод makeSound , который выводит на консоль строку
"Woof woof!" вместо того, что выводит метод makeSound класса Animal .
При вызове метода makeSound на экземпляре класса Dog , будет вызван
переопределенный метод makeSound , который выводит строку "Woof woof!".
Если в переопределенном методе нужно вызвать унаследованный метод, можно
использовать ключевое слово super .
class Animal {
makeSound() {
console.log("Animal is making a sound");
}
}
woof!". При вызове метода makeSound на экземпляре класса Dog , будет вызван
переопределенный метод makeSound , который выводит строки "Animal is making a
sound" и "Woof woof!".
instanceof
5.1. class 10
- это оператор в JavaScript, который используется для проверки,
instanceof
class Animal {}
class Car {}
5.1. class 11
Примеси (mixins)
Начнем с того, что в JavaScript не существует множественного наследования. То
есть мы не можем наследовать класс от нескольких классов.
Примеси как раз и решают эту проблему. Они представляют собой способ
повторного использования кода, позволяющий добавлять в классы
дополнительные свойства и методы из других объектов.
const myMixin = {
mixinMethod() {
console.log('Этот метод из миксина');
}
};
class MyClass {
// ...
}
Object.assign(MyClass.prototype, myMixin);
5.1. class 12
внимательно выбирать имена методов, а также контролировать их использование
в коде.
Задания
1. Создай класс Rectangle с двумя свойствами: width и height . Добавь метод
getArea() , который будет возвращать площадь прямоугольника.
student .
5.1. class 13
isMan. Boolean. true || false;
https://forms.gle/7kG4ZznWkB1VgQqKA
Наследование
Наследование в JavaScript - это механизм, который позволяет одному классу
(дочернему) наследовать свойства и методы другого класса (родителя).
Пример наследования в JavaScript
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} шумит.`);
}
}
В данном примере класс Dog наследует все свойства и методы класса Animal и
может их использовать и переопределять.
Но надо помнить, что “под капотом” JavaScript использует прототипное
наследование. Это означает, что объекты наследуют свойства и методы от своего
прототипа, который является другим объектом.
Инкапсуляция
Инкапсуляция - это механизм ООП, который ограничивает доступ к свойствам и
методам класса снаружи.
Пример инкапсуляции в JavaScript
В этом примере я использую _balance как закрытое свойство класса, и мы можем
использовать методы get и set для доступа к нему.
class BankAccount {
constructor(balance) {
this._balance = balance;
}
get balance() {
return this._balance;
}
set balance(amount) {
if (amount < 0) {
console.log("Невозможно установить отрицательный баланс");
return;
}
this._balance = amount;
}
deposit(amount) {
this.balance += amount;
}
withdraw(amount) {
if (this.balance - amount < 0) {
console.log("Недостаточно средств");
return;
}
Полиморфизм
Полиморфизм в JavaScript - это возможность использовать один и тот же метод
для различных инстансов класса (объектов).
class Shape {
draw() {
console.log("Рисуем фигуру");
}
}
Абстракция
Абстракция в JavaScript означает создание структуры свойств и методов,
которые могут быть использованы для представления конкретного объекта или
категории объектов. Посмотри вокруг. Тебя окружают объекты!! Реализуешь их в
JS - это и будет абстракцией.
Пример абстракции в JavaScript
class Car {
constructor(make, model) {
this.make = make;
this.model = model;
}
honk() {
console.log('Бип-бип!');
}
}
P.S Если тебе стало понятнее и понравились примеры, отправь мне в личку
function syncCode() {
console.log("начало");
console.log("первый");
console.log("второй");
console.log("конец");
}
syncCode();
Этот код выполнится синхронно, и выведет в консоль все строки по порядку, так
как каждая операция будет блокировать выполнение следующей.
function asyncCode() {
console.log("начало");
setTimeout(() => {
console.log("первый");
}, 2000);
setTimeout(() => {
console.log("второй");
}, 1000);
console.log("конец");
}
asyncCode();
setTimeout
- это функция, которая позволяет задать отсрочку выполнения
setTimeout
function sayHello() {
console.log("Привет, мир!");
}
1) https://habr.com/ru/post/651037/
2) https://habr.com/ru/post/439620/
function sayName(){
return "Pavel";
}
function sayHi(callback){
console.log(`Hi, ${callback()}`)
}
sayHi(sayName);
Еще пример:
6.2. callback 1
function someFunction(arg1, arg2, callback) {
const result = arg1 + arg2;
callback(result);
}
function myCallback(result) {
console.log('Результат: ' + result);
}
someFunction(2, 3, myCallback);
Callback hell
Callback hell - это ситуация, когда вложенные асинхронные функции вызывают
друг друга с использованием обратных вызовов, что приводит к громоздкому и
сложному для понимания коду. Код становится сложнее поддерживать,
отлаживать и масштабировать. Примеры таких ситуаций могут включать
последовательные запросы к API или обработку больших объемов данных.
function getData(callback) {
someAsyncFunction(function(result) {
anotherAsyncFunction(result, function(newResult) {
yetAnotherAsyncFunction(newResult, function(finalResult) {
callback(finalResult);
});
});
});
}
function getData() {
return someAsyncFunction()
.then(result => anotherAsyncFunction(result))
6.2. callback 2
.then(newResult => yetAnotherAsyncFunction(newResult))
}
Код использует промисы вместо обратных вызовов, чтобы сделать код более
линейным и уменьшить количество вложенности. Код становится более
понятным и проще для понимания.
Задания
1. Напиши функцию sumNumbers, которая принимает два числа a и b и callback-
функцию. Функция должна сложить числа a и b и передать результат в
callback-функцию которая выведет результат в консоль.
6.2. callback 3
Помоги сделать эту эту главу лучше! Дай обратную связь, а мы
прислушаемся к ней и сделаем ЛУЧШИЙ учебник по JavaScript для тебя и
остальных студентов!
Заполни форму
https://forms.gle/GjKWUxTxWKqQJqVM7
6.3. Promise
6.2. callback 4
6.3. Promise
Промис (Promise) - это объект в JavaScript, который представляет собой
неопределенное значение, которое будет вычислено в будущем. Промисы
используются для работы с асинхронным кодом, который выполняется не сразу, а
после выполнения какой-то операции, которая может занять время. Например,
загрузка данных с сервера.
6.3. Promise 1
(callback hell), при использовании промисов можно использовать цепочку
методов, что делает код более читабельным и легко поддерживаемым.
promise
.then((result) => {
console.log(result); // "Привет, Redev!"
})
.catch((error) => {
console.error(error);
});
{
state: "pending" || "fulfilled" || "rejected",
result: undefined || value || error
}
6.3. Promise 2
ожидание (pending)
выполнено (fulfilled)
отклонено (rejected).
То есть зафиксируем:
Промис - это объект. У этого объекта есть свойства state и result и методы
.then() и .catch() . Создается промис с помощью конструктора new Promise() . У
.then()
Метод then() вызывается, когда промис переходит в состояние выполнено, т.е.
когда асинхронная операция завершается успешно.
6.3. Promise 3
Этот метод принимает две callback-функции - одну для обработки успешно
разрешенного промиса (fulfilled), а другую для обработки отклоненного промиса
(rejected).
promise.then(onFulfilled, onRejected)
promise.then(
(result) => console.log(result), // сработает в случае resolve
(error) => console.log(error) // сработает в случае reject
);
где:
.catch()
Метод .catch() позволяет обрабатывать ошибки в асинхронных операциях. Он
представляет собой сокращенную запись для обработки отклонений промисов и
является альтернативой использованию второго аргумента (onRejected) метода
then().
Он вызывается только в том случае, если промис был отклонен, и принимает один
аргумент - error.
promise.catch(onRejected)
6.3. Promise 4
где:
.finally()
Метод .finally() является одним из методов промисов и позволяет выполнить
определенное действие, когда промис завершается, независимо от того, был он
разрешен успешно или отклонен с ошибкой. То есть он отработает ВСЕГДА!!!
promise.finally(onFinally)
myPromise
.then((result) => {
console.log(result);
})
.catch((error) => {
console.error(error);
})
.finally(() => {
console.log('Promise completed!'); //выполнится в любом случае
});
где:
Цепочка промисов
Цепочка промисов (Promise chaining) - это способ последовательного выполнения
нескольких асинхронных операций с помощью промисов. Этот подход позволяет
6.3. Promise 5
упростить и сократить код, а также делает его более понятным и
поддерживаемым.
promise
.then(data => data + 2)
.then(data => {
console.log(data) // 3
return data + 2;
})
.then(data => console.log(data)) // 5
promise
.then(data => new Promise(resolve => resolve(data + 2)))
.then(data => {
console.log(data) // 3
return new Promise(resolve => resolve(data + 2))
})
.then(data => console.log(data)) // 5
Пример с .catch()
Пример 1
В примере ниже в консоли, если мы его запустим, увидим “1” и “2” .
6.3. Promise 6
Почему же так? Давай разбираться.
Промис завершается с ошибкой (reject), соответственно его обрабатывает
первый .catch() и выводит “1” . !!!Все, ошибки больше нет!! Дальше по цепочке
промис идет успешно завершенный (state: fulfilled). Соответственно следующим
выполнится метод .then() и выведет “2” в консоль и так же завершится успешно,
по этому последний .catch() не выполнится.
Пример 2
Теперь предлагаю рассмотреть второй пример. Как думаешь, что выведет в
консоль?
Класс Promise
В классе Promise есть полезные статические методы:
6.3. Promise 7
2. Promise.reject(error) : возвращает новый отклоненный promise с переданной
причиной.
6.3. Promise 8
const result = Promise.race([promise1,promise2,promise3]);
const promises = [
Promise.resolve('Promise 1 resolved'),
Promise.reject('Promise 2 rejected'),
Promise.resolve('Promise 3 resolved')
];
Promise.allSettled(promises)
.then(results => {
console.log(results);
});
массива объектов:
6.3. Promise 9
[
{state: "fulfilled", value: "Promise 1 resolved"},
{state: "rejected", reason: "Promise 2 rejected"},
{state: "fulfilled", value: "Promise 3 resolved"}
]
Задания
1. Напиши функцию, которая получает на вход два числа и возвращает
Promise, который разрешается через 1 секунду с результатом суммы этих
чисел. Если одно из чисел не является числом, Promise должен быть
отклонен с ошибкой.
6.3. Promise 10
Помоги сделать эту эту главу лучше! Дай обратную связь, а мы
прислушаемся к ней и сделаем ЛУЧШИЙ учебник по JavaScript для тебя и
остальных студентов!
Заполни форму
https://forms.gle/2W7LgHkfWLec3zdv6
🔄 6.4. async/await
6.3. Promise 11
🔄
6.4. async/await
Асинхронные функции (async/await) — это способ написания асинхронного кода,
который делает его более легким для чтения и написания, по сравнению с
использованием callback-ов или промисов.
Ключевые слова async и await в JavaScript предназначены для работы с
асинхронным кодом и облегчения его написания и понимания.
async используется для объявления асинхронной функции, которая возвращает
промис. Когда асинхронная функция вызывается, она начинает выполнение, и
затем возвращает промис, который может быть зарезолвлен или отклонен после
завершения выполнения функции.
6.4. async/await 1
getData();
Пример:
6.4. async/await 2
Если же промис завершается с ошибкой, управление передается в блок catch ,и
мы можем обработать ошибку.
Задания
1. Напиши функцию, которая принимает на вход строку и возвращает промис,
который разрешается через указанное количество миллисекунд, где
количество миллисекунд равно длине строки.
6.4. async/await 3
🔂
6.5. Event Loop
1. Call Stack (стек вызовов) - это механизм, который используется для хранения
вызовов функций в порядке их вызова. Когда функция вызывается, она
помещается в вершину стека, а когда она завершается, она удаляется из
стека. Таким образом, стек вызовов используется для выполнения синхронного
кода в порядке вызова функций.
4. Event Loop (цикл событий) - это механизм, который постоянно проверяет стек
вызовов и очередь обратных вызовов. Когда стек вызовов пуст, Event Loop
извлекает первый обратный вызов из очереди и помещает его в стек вызовов
для выполнения. Таким образом, Event Loop обеспечивает выполнение
асинхронного кода в правильном порядке и в том же самом потоке
выполнения.
Задания
1. Что попадет в микротаск, а что в макротаск?
console.log(1);
console.log(3);
console.log(4);
Структура HTTP-сообщения
Каждое сообщение HTTP состоит из трех частей, которые передаются в указанном
порядке:
Методы
Тип HTTP-запроса (также называемый HTTP-метод) указывает серверу на то,
какое действие мы хотим произвести с ресурсом.
GET
PUT
PATCH
DELETE
OPTIONS
HEAD
GET
Используется для получения информации с указанного источника.
POST
Используется для отправки информации, введенной пользователем, на сервер.
Например, при заказе пиццы 🍕
онлайн. Эта информация затем отправляется на
сервер с помощью метода POST и отображаются на странице пиццерии. Данные,
отправляемые на сервер (в примере с пиццей - заказ), включаются в тело запроса.
Также метод POST используется для загрузки файлов на сервер.
const order = {
item: ['Peperoni'],
city: "Minsk",
telNumber: "+375291231231"
PUT
Используется для загрузки содержимого запроса по указанному в запросе адресу
(URL). Если по этому адресу не существует ресурса, сервер будет создавать его и
возвращать статус 201 (Created). Если ресурс был изменен, сервер вернет 200
(Ok) или 204 (No Content).
const editOrder = {
item: ['Peperoni'],
city: "Brest",
telNumber: "+375291231231"
}
PATCH
Аналогично PUT, но применяется только к фрагменту ресурса.
PATCH и PUT оба используются для обновления ресурсов на сервере
Однако они имеют разное поведение:
const editOrder = {
city: "Brest",
}
DELETE
Удаляет указанный ресурс.
Обычно DELETE запрос не имеет тела, но если необходимо, то может содержать.
Но это не является обязательным.
HEAD
Метод HEAD похож на метод GET, но в ответе сервера нет тела. Он обычно
используется для получения метаданных, проверки наличия ресурса и для
определения, изменился ли он с последнего обращения.
OPTIONS
Метод OPTIONS используется для запроса сведений о доступных методах HTTP
для ресурса. Он может использоваться для получения списка поддерживаемых
методов или для проверки, поддерживает ли сервер определенный метод для
данного ресурса. Ответ сервера содержит заголовок Allow, который перечисляет
поддерживаемые методы. Метод OPTIONS часто используется в связке с методом
CORS (Cross-Origin Resource Sharing), чтобы указать браузеру, какие методы и
заголовки могут использоваться для кросс-доменных запросов.
Коды состояния HTTP используются для того, чтобы указать клиенту, как
обрабатывать ответ сервера. Они показывают, был ли запрос успешным или нет, и
какую информацию необходимо получить из ответа. Например, код 200 OK
указывает на то, что запрос был успешным и в ответе содержится запрашиваемая
информация, а код 404 Not Found указывает на то, что запрашиваемый ресурс не
найден.
Категории
Все коды делятся на 5 основных классов, каждый из которых обозначается первой
цифрой кода:
Методы POST и PUT используются для отправки данных на сервер, но они имеют
разное применение и разные свойства идемпотентности.
Задание
API documentation - https://first-node-js-app-r.herokuapp.com/api-docs/
1. Зарегистрировать пользователя
6. Удалить таску
* Для работы 3,4,5,6 нужен токен. Его можно получить один раз и
переиспользовать.
* Надо разобраться с документацие swagger. Что к чему там. Удачи 🍀
Полезное видео - https://www.youtube.com/watch?v=oXTPrWva9pc
Про Swagger - https://habr.com/ru/amp/post/434798/
https://forms.gle/eTswQrw39piDCJUn8