From c91b22365acd122bca33468ecfc70fdf8cca57e2 Mon Sep 17 00:00:00 2001 From: Vasil Vanchuk Date: Fri, 3 Oct 2025 21:05:26 +0300 Subject: [PATCH 1/2] Update titles. Add lectures --- lessons/lesson15/lesson.md | 2 +- lessons/lesson19/lesson.md | 571 ++++++++++++++++++++++++++++++++++++- lessons/lesson20/lesson.md | 426 ++++++++++++++++++++++++++- lessons/lesson23/lesson.md | 5 + lessons/lesson24/lesson.md | 5 + 5 files changed, 1006 insertions(+), 3 deletions(-) diff --git a/lessons/lesson15/lesson.md b/lessons/lesson15/lesson.md index bd7c60e..6da4ca8 100644 --- a/lessons/lesson15/lesson.md +++ b/lessons/lesson15/lesson.md @@ -1,5 +1,5 @@ --- -title: Занятие 4.1 +title: Занятие 15 description: Базовое использование API и JavaScript. Как работать с DOM и другими доступными API --- diff --git a/lessons/lesson19/lesson.md b/lessons/lesson19/lesson.md index a5daf6f..ba1af39 100644 --- a/lessons/lesson19/lesson.md +++ b/lessons/lesson19/lesson.md @@ -1 +1,570 @@ -# Lesson 19 +--- +title: Занятие 19 +description: Контекст при работе с функциями +--- + +# OTUS + +## Javascript Basic + + + +### Вопросы? + + + +### Контекст при работе с функциями + + + +### Функции + + + +- тип данных - object +- ссылочный тип данных +- `typeof` возвращает `function` + + + +Характеристики функции: + +- Имя функции +- Число и тип параметров +- Тип возвращаемого значения +- Контекст + + + +#### Способы создания функции + + + +```js [1-30] +// Создание функции 1 +// Function declaration +// - работает hosting +// - всегда есть имя +function greet1(name) { + console.log("Hello, " + name); +} +greet1(); +``` + + + +```js [1-30] +// Создание функции 2 +// Functional Expression +// - не работает хоистинг инициализации (хоистинг объявления зависит от типа переменной) +// - имя опционально (а если задано - доступно ТОЛЬКО внутри функции) +let greet2 = function innerGreetName(name) { + console.log("Hello, " + name); +}; +let greet22 = function (name) { + console.log("Hello, " + name); +}; +greet2(); +``` + + + +```js [1-30] +// Создание функции 3 +// Function by constructor +// - не работает хоистинг инициализации (хоистинг объявления зависит от типа переменной) +// - имени нет, или нужно задавать вручную +let greet3 = new Function("name", "return 'Hola, ' + name;"); +greet3(); +``` + + + +**Функции высшего порядка** - функции, которые принимают параметром и/или возвращают функции как результат работы. + + + +```js [1-30] +let createGreet = function (age) { + let text = age > 18 ? "Приветствую" : "Хаюшки"; + return function (name) { + console.log(text + ", " + name); + }; +}; +let greet1 = createGreet(45); +greet1("Роберт"); // ? +let greet2 = createGreet(11); +greet2("Саня"); // ? +``` + + + +```js [1-30] +document.findElementById("btn").addEventListener("click", function () { + alert("*Opa!"); +}); +``` + + + +Функция - объект + +```js [1-30] +let greet = function (name) { + return "Hi, " + name; +}; +console.log(typeof greet); // ? + +console.log(greet.hasOwnProperty("hasOwnProperty")); +console.log(greet.hasOwnProperty("toString")); +console.log(greet.toString()); +``` + + + +Функция может быть свойством объекта + +```js [1-30] +let o = { + method: function (param) { + console.log("Do something with", param); + }, +}; +o.method("icecream"); // ? +``` + + + +### Вопросы? + + + +#### Замыкания + + + +Замыкания в JS - механизм, который позволяет внутри функции получать доступ к переменным, доступным в месте создания функции. + + + +```js [1-30] +var createGreet = function (age) { + var text = age > 18 ? "Приветствую" : "Хаюшки"; + return function (name) { + console.log(text + ", " + name); + }; +}; +var greet1 = createGreet(45); +greet1("Роберт"); +``` + + + +```js [1-30] +function getCounter() { + let i = 0; + return { + next: function () { + i = i + 1; + }, + reset: function () { + i = 0; + }, + current: function () { + return i; + }, + }; +} +let counter = getCounter(); +console.log(counter.current()); // ? +counter.next(); +counter.next(); +console.log(counter.current()); // ? +counter.reset(); +console.log(counter.current()); // ? +``` + + + +Доступ к параметрам функции + +- по имени +- через [`arguments`](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Functions/arguments) (не работает в стрелочных функциях) + + + +Для работы с неопределенным числом параметров принято использовать [`rest params`](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Functions/Rest_parameters) + +```js [1-30] +function sum(...values) { + return values.reduce((acc, el) => acc + el); +} + +function myFun(a, b, ...manyMoreArgs) { + console.log("a", a); + console.log("b", b); + console.log("manyMoreArgs", manyMoreArgs); +} +``` + + + +### Вопросы? + + + +### Особенности работы с функциями + + + +#### Контекст (`this`) + + + +Контекст - определяет в рамках какого **объекта** **выполняется функция**. Определяется тем, какое значение имеет ключевое слово [`this`](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Operators/this) **при выполнении** функции. + +Позволяет изменять/задавать поведение функции. + + + +[Строгий режим Javascript](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Strict_mode) - использование ограниченной семантики языка для улучшения стабильности, и который упрощает понимание того, что происходит в программе при возникновении проблем. + +Обычный, нестрогий, режим выполнения JavaScript иногда называется Грязным режимом (Sloppy mode). + + + +Три возможных варианта + +- window +- undefined +- объект + + + +```js [1-30] +// window +function someStrangeFunction() { + console.log("this for someStrangeFunction", this); +} +someStrangeFunction(); +``` + + + +```js [1-30] +"use strict"; +// undefined +function someStrangeFunction() { + console.log("this for someStrangeFunction", this); +} +someStrangeFunction(); +``` + + + +```js [1-30] +// object +var o = { + prop1: 1, + someStrangeFunctionInObject: function () { + console.log("this for someStrangeFunctionInObject", this); + }, +}; +o.someStrangeFunctionInObject(); +``` + + + +```js [1-30] +var o = { + prop1: 1, + someStrangeFunctionInObject: function () { + console.log("this for someStrangeFunctionInObject", this); + }, +}; +let func = o.someStrangeFunctionInObject; +func(); //? +``` + + + +```js [1-30] +function someStrangeFunction() { + console.log("this for someStrangeFunction", this); +} +let o = { prop1: 1 }; +someStrangeFunction(); // ? +o.someStrangeMethod = someStrangeFunction; +o.someStrangeMethod(); // ? +``` + + + +```js [1-30] +// Об этом важно помнить при передаче методов +let o = { + name: "Bob", + greet: function () { + console.log("Hello, " + this.name); + }, +}; +document.body.addEventListener("click", o.greet); +``` + + + +```js [1-30] +let o = { + name: "Bob", + greet: function () { + console.log("Hello, " + this.name); + }, +}; +let x = o.greet; +x(); // ? +``` + + + +#### Изменение и фиксирование контекста + + + +```js [1-30] +let o = { prop1: 1, name: "Sam" }; +let f = function () { + console.log(this); +}; +f(); // ? +``` + + + +```js [1-30] +let o = { prop1: 1, name: "Sam" }; +let f = function (x) { + console.log(this, x); +}; +o.of = f; +o.of(1); // o, 1 +f.call(o, 2); // o, 2 +f.apply(o, [3]); // o, 3 + +var of = f.bind(o); +of(4); // o, 4 +``` + + + +```js [1-30] +let o = { prop1: 1, name: "Sam" }; +let f = function (name) { + console.log(this, name); +}; + +f.call(o, "user 2"); // параметры один за одним +f.apply(o, ["user 3"]); // параметры списком + +f.bind(o)("user 4"); // bind возвращает функцию для вызова +``` + + + +### Вопросы? + + + +[Практика](https://codesandbox.io/s/github/vvscode/otus--javascript-basic/tree/master/lessons/lesson03/code/bind) + +Напишите функцию, которая позволит привязывать контекст, так, как это делает метод `.bind` (сам метод использовать нельзя). + + + +### Вопросы? + + + +### [Стрелочные функции](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Functions/Arrow_functions) + + + +- короткий синтаксис +- только Functional expression +- нет имени +- привязаны к значению `this`, который определяется в момент определения функции (кроме class properties) +- не могут быть конструкторами +- в них не работают `arguments` / `new.target` / `super` / `yeild` +- удобны для inline использования + + + +```js [1-30] +// блочная форма +let double1 = (a) => { + return a * 2; +}; +// Когда один аргумент - скобки можно опускать +// prettier-ignore +let double2 = a => { + return a * 2; +}; +// При коротком возвращении - блок и return можно опускать +// prettier-ignore +let double3 = a => a * 2; +// а иногда (НО не пишите так никогда) +// prettier-ignore +let func = _ => new Date().toLocaleTimeString(); +``` + + + +```js [1-30] +// НО! +let func1 = () => { + foo: 1; +}; +func(); // undefined + +let func2 = () => ({ foo: 1 }); + +func2(); // { foo: 1 } +``` + +[Про label](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Statements/label) + + + +```js [1-30] +let o = { + name: "Bob", + greet: () => { + console.log("Hello, " + this.name); + }, +}; +document.body.addEventListener("click", o.greet); //? +``` + + + +```js [1-30] +function O() { + this.name = "Bob"; + this.greet = () => { + console.log("Hello, " + this.name); + }; +} +document.body.addEventListener("click", new O().greet); //? +``` + + + +```js [1-30] +let O = function () { + this.name = "Bob"; + this.greet = () => { + console.log("Hello, " + this.name); + }; +}; +let greet = new O().greet; +greet.call({ name: "Sam" }); // ? +``` + + + +### Вопросы? + + + +### Что со всем этим делать? + +_Понять, простить и пользоваться_ + + + +- [Использовать чужие методы на своих объектах](https://learn.javascript.ru/native-prototypes#zaimstvovanie-u-prototipov) + + + +### Дополнительные материалы + + + +- [Продвинутая работа с функциями](https://learn.javascript.ru/advanced-functions) + + + +### Вопросы? + + + +#### Вопросы для самопроверки + +Как проверить, что вы усваиваете материал в срок (не все из этого давалось на занятиях) + + + +1. Что такое контекст вызова функции? Чем определяется? + +2. Как изменить this внутри функции? (5 способов) + +3. чем различаются .call / .apply / .bind + +4. Что такое сигнатура функции? + +5. Чем характеризуется функция? + + + +6. Что такое прототип? + +7. Как работает конструктор? Что происходит при вызове со словом new ? + +8. Как происходит чтение свойств из объекта? + +9. Как происходит запись свойств в объект? + +10. Как проверить на принадлежность классу? + + + +11. Как работает instanceof ? + +12. Четыре принципа ООП + +13. Виды полиморфизма. И их объяснение + +14. Событийный цикл в javascript + +15. Что такое фаза захвата / capturing ? + + + +16. Что такое фаза всплытия / bubbling ? + +17. Как подписаться на событие документа / html элемента? + +18. Что такое Функция высшего порядка? + +19. Что такое синхронный / асинхронный код? + +20. Что такое каррирование ? + + + +21. Что такое паттерн цепочка ? Как реализовать? + +22. В чем разница объявления методов в конструкторе и на .prototype ? + +23. Что такое 'полифилл'? + +24. Что такое "стрелочная" ("arrow function") функция? Чем она отличается от обычной? + +25. Что такое CORS? + + + +26. Что такое и какие есть коды ответов HTTP? + +27. Что такое делегирование событий? Преимущества и особенности работы с делегированием? + + diff --git a/lessons/lesson20/lesson.md b/lessons/lesson20/lesson.md index c365d03..aae453a 100644 --- a/lessons/lesson20/lesson.md +++ b/lessons/lesson20/lesson.md @@ -1 +1,425 @@ -# Lesson 20 +--- +title: Занятие 20 +description: Прототипное наследование и функции-конструкторы +--- + +# OTUS + +## Javascript Basic + + + +### Вопросы? + + + +### Прототипное наследование и функции-конструкторы + + + +### Создание объектов + + + +```js [1-30] +const user = { + name: "Bob", +}; +``` + + + +Достаточно часто, нам нужно создавать много однотипных объектов + +```js [1-30] +function getUser(name) { + return { + name: name, + }; +} + +const user1 = getUser("Bob"); +const user2 = getUser("Sam"); +``` + + + +И часто объекты сопровождаются не просто свойствами, а свойствами-методами (функциями) + +```js [1-30] +function getUser(name) { + return { + name, + greet: function () { + alert(`Hello from ${this.name}`); + }, + }; +} + +const user1 = getUser("Bob"); +const user2 = getUser("Sam"); + +user1.greet(); +``` + +в чем проблема такого кода? + + + +Используем прототипы для экономии памяти + + + +```js [1-30] +const userPrototype = { + greet() { + alert(`Hello from ${this.name}`); + }, +}; + +function getUserWithPrototype(name) { + return { + name, + __proto__: userPrototype, + }; +} + +const user1 = getUserWithPrototype("Bob"); +const user2 = getUserWithPrototype("Sam"); + +user1.greet(); +``` + + + +```js [1-30] +const userPrototype = { + greet() { + alert(`Hello from ${this.name}`); + }, +}; + +function getUserWithPrototype(name) { + return Object.create(userPrototype, { + name: { + value: name, + }, + }); +} +const user1 = getUserWithPrototype("Bob"); +const user2 = getUserWithPrototype("Sam"); + +user1.greet(); +``` + + + +### Вопросы? + + + +#### Работа с конструкторами + + + +Для упрощения создания объектов в языке предусмотрен механизм вызова функции в качестве конструкторов. + +Это, к слову, еще один способ изменить `this` (в дополнение к тем, что мы уже рассмотрели) - использовать ключевое слово `new` + + + +Алгоритм работы конструктора: + +- `new` с любой функцией (кроме стрелочной) создает новый объект +- созданный объект получает значение `__proto__` (из свойства конструктора `prototype`) +- созданный объект ассоциируется с `this` +- выполняется функция +- если функция возвращает примитивное значение - неявно возвращается `this` + + + +```js [1-30] +var f = function (name) { + console.log(this); +}; +f("Sam"); // ? +console.log(new f("Bob")); // ? +``` + + + +```js [1-30] +function User(name, greet) { + // изменяем новый объект при создании + this.name = name; + this.greetPhrase = greet; + this.greet = function () { + console.log(this.greetPhrase + ", " + this.name); + }; +} +let u1 = new User("Bob", "Hello"); +let u2 = new User("Sam", "hi"); +console.log(u1, u2); +u1.greet(); +u2.greet(); +``` + + + +```js [1-30] +function User(name, greet) { + this.name = name; + this.greetPhrase = greet; +} +User.prototype = { + greet: function () { + console.log(this.greetPhrase + ", " + this.name); + }, +}; +let u1 = new User("Bob", "Hello"); +let u2 = new User("Sam", "hi"); +console.log(u1, u2); +u1.greet(); +u2.greet(); +``` + + + +```js [1-30] +function User(name, greet) { + this.name = name; + // читаем greet через замыкание + this.greet = function () { + console.log(greet + ", " + this.name); + }; +} +let u1 = new User("Bob", "Hello"); +u1.greet(); +document.body.addEventListener("click", u1.greet); +``` + + + +```js [1-30] +function User(name, greet) { + this.name = name; + // Фиксируем контекст + this.greet = () => { + console.log(greet + ", " + this.name); + }; +} +let u2 = new User("Bob", "Hello"); +u2.greet(); +document.body.addEventListener("click", u2.greet); +``` + + + +Нужно отметить, что задание прототипа, это [не единственное, что делают конструкторы](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Classes/constructor) + + + +Функции-конструкторы - вариант создания "классов" до-ES6 мира. В целом, современные классы являются "синтаксическим сахаром" и так же работают на прототипах, просто позволяют нам использовать другой синтаксис для описания. + + + +```js [1-30] +// ES5 +function User(name, greet) { + this.name = name; + this.greetPhrase = greet; +} +User.prototype = { + greet: function () { + console.log(this.greetPhrase + ", " + this.name); + }, +}; +``` + + + +```js [1-30] +// ES6 +class User { + constructor(name, greet) { + this.name = name; + this.greetPhrase = greet; + } + + greet() { + console.log(this.greetPhrase + ", " + this.name); + } +} + +console.log(User.prototype); +let u3 = new User("Bob", "Hello"); +u3.greet(); +document.body.addEventListener("click", u3.greet); +``` + + + +```js [1-30] +// ES6 +class User { + constructor(name, greet) { + this.name = name; + this.greetPhrase = greet; + } + + // https://babeljs.io/docs/en/babel-plugin-proposal-class-properties + greet = () => { + console.log(this.greetPhrase + ", " + this.name); + }; +} + +console.log(User.prototype); +let u4 = new User("Bob", "Hello"); +u4.greet(); +document.body.addEventListener("click", u4.greet); +``` + + + +### Вопросы? + + + +#### Как проверить, что объект является экземпляром класса? + + + +```js [1-30] +function User() {} +var fu = {}; +var u = new User(); + +console.log(fu, fu instanceof User); +console.log(u, u instanceof User); +``` + + + +`instanceof` ходит по цепочке прототипов и ищет совпадение с `prototype` + +``` +x instanceof Y +-> x.__proto__ === Y.prototype +-> x.__proto__.__proto__ === Y.prototype +-> ... +``` + + + +```js [1-30] +let o = {}; +console.log(o instanceof Array); // ? + +o.__proto__ = []; + +// o.__proto__.__proto__ === Array.prototype +console.log(o instanceof Array); +``` + + + +### Вопросы? + + + +[Практика](https://codesandbox.io/s/github/vvscode/otus--javascript-basic/tree/master/lessons/lesson03/code/singleton) + +Напишите функцию или класс, которые будут являться синглтоном. + +Напишите функцию, которая делает синглтоны на основе других классов. + + + +### Вопросы? + + + +### Что со всем этим делать? + +_Понять, простить и пользоваться_ + + + +- Читать документацию, например [методы функций](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Function) / [другие встроенные объекты](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects) +- [Monkey patching](https://learn.javascript.ru/native-prototypes#native-prototype-change) + + + +### [Домашнее задание](https://github.com/vvscode/otus--javascript-basic/blob/master/lessons/lesson03/homework_lec3.md) + + + +#### Вопросы для самопроверки + +Как проверить, что вы усваиваете материал в срок (не все из этого давалось на занятиях) + + + +1. Что такое контекст вызова функции? Чем определяется? + +2. Как изменить this внутри функции? (5 способов) + +3. чем различаются .call / .apply / .bind + +4. Что такое сигнатура функции? + +5. Чем характеризуется функция? + + + +6. Что такое прототип? + +7. Как работает конструктор? Что происходит при вызове со словом new ? + +8. Как происходит чтение свойств из объекта? + +9. Как происходит запись свойств в объект? + +10. Как проверить на принадлежность классу? + + + +11. Как работает instanceof ? + +12. Четыре принципа ООП + +13. Виды полиморфизма. И их объяснение + +14. Событийный цикл в javascript + +15. Что такое фаза захвата / capturing ? + + + +16. Что такое фаза всплытия / bubbling ? + +17. Как подписаться на событие документа / html элемента? + +18. Что такое Функция высшего порядка? + +19. Что такое синхронный / асинхронный код? + +20. Что такое каррирование ? + + + +21. Что такое паттерн цепочка ? Как реализовать? + +22. В чем разница объявления методов в конструкторе и на .prototype ? + +23. Что такое 'полифилл'? + +24. Что такое "стрелочная" ("arrow function") функция? Чем она отличается от обычной? + +25. Что такое CORS? + + + +26. Что такое и какие есть коды ответов HTTP? + +27. Что такое делегирование событий? Преимущества и особенности работы с делегированием? diff --git a/lessons/lesson23/lesson.md b/lessons/lesson23/lesson.md index fd4955f..55f36cf 100644 --- a/lessons/lesson23/lesson.md +++ b/lessons/lesson23/lesson.md @@ -1,3 +1,8 @@ +--- +title: Занятие 23 +description: Разделение логики и представления +--- + # Lesson 23 ## OTUS Javascript Basic diff --git a/lessons/lesson24/lesson.md b/lessons/lesson24/lesson.md index 6b4afa1..2f4baf2 100644 --- a/lessons/lesson24/lesson.md +++ b/lessons/lesson24/lesson.md @@ -1,3 +1,8 @@ +--- +title: Занятие 24 +description: Разбиение кода на модули (чистые функции, внедрение зависимостей, принцип единственной ответственности) +--- + ## OTUS Javascript Basic ### Разбиение кода на модули (чистые функции, внедрение зависимостей, принцип единственной ответственности) From 7f794ea124c7085cab751f822d735b65ab651a0a Mon Sep 17 00:00:00 2001 From: Vasil Vanchuk Date: Fri, 3 Oct 2025 21:08:49 +0300 Subject: [PATCH 2/2] Add faq lessons --- lessons/lesson01/lesson.md | 5 +++++ lessons/lesson02/lesson.md | 5 +++++ lessons/lesson11/lesson.md | 5 +++++ lessons/lesson14/lesson.md | 5 +++++ lessons/lesson18/lesson.md | 5 +++++ lessons/lesson26/lesson.md | 5 +++++ 6 files changed, 30 insertions(+) diff --git a/lessons/lesson01/lesson.md b/lessons/lesson01/lesson.md index 90f316c..cbbb57c 100644 --- a/lessons/lesson01/lesson.md +++ b/lessons/lesson01/lesson.md @@ -1 +1,6 @@ +--- +title: Занятие 1 +description: Консультация №1 по итогам просмотра первой части подготовительного курса +--- + # Lesson 1 diff --git a/lessons/lesson02/lesson.md b/lessons/lesson02/lesson.md index 69326b8..19b88e2 100644 --- a/lessons/lesson02/lesson.md +++ b/lessons/lesson02/lesson.md @@ -1 +1,6 @@ +--- +title: Занятие 2 +description: Консультация №2 по итогам просмотра первой части подготовительного курса +--- + # Lesson 2 diff --git a/lessons/lesson11/lesson.md b/lessons/lesson11/lesson.md index 7d880b5..2c11ce5 100644 --- a/lessons/lesson11/lesson.md +++ b/lessons/lesson11/lesson.md @@ -1 +1,6 @@ +--- +title: Занятие 11 +description: Консультация по ДЗ +--- + # Lesson 11 diff --git a/lessons/lesson14/lesson.md b/lessons/lesson14/lesson.md index a192912..4b7f063 100644 --- a/lessons/lesson14/lesson.md +++ b/lessons/lesson14/lesson.md @@ -1 +1,6 @@ +--- +title: Занятие 14 +description: Консультация по ДЗ +--- + # Lesson 14 diff --git a/lessons/lesson18/lesson.md b/lessons/lesson18/lesson.md index 7daf403..04c8eee 100644 --- a/lessons/lesson18/lesson.md +++ b/lessons/lesson18/lesson.md @@ -1 +1,6 @@ +--- +title: Занятие 18 +description: Консультация по ДЗ +--- + # Lesson 18 diff --git a/lessons/lesson26/lesson.md b/lessons/lesson26/lesson.md index e206a78..e7025ae 100644 --- a/lessons/lesson26/lesson.md +++ b/lessons/lesson26/lesson.md @@ -1 +1,6 @@ +--- +title: Занятие 26 +description: Консультация по ДЗ +--- + # Lesson 26