You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 1-js/09-classes/07-mixins/article.md
+18-17Lines changed: 18 additions & 17 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,7 +4,7 @@
4
4
5
5
Иногда это может ограничивать нас. Например, у нас есть класс `StreetSweeper` и класс `Bicycle`, а мы хотим создать `StreetSweepingBicycle`.
6
6
7
-
Или, говоря о программировании, у нас есть класс `Renderer`, который реализует шаблон, и класс `EventEmitter`, реализующий событие. Мы хотели бы объединить их функционал в классе `Page`, чтобы создать страницу, которая будет использовать шаблон и запускать событие.
7
+
Или, говоря о программировании, у нас есть класс `User`, который реализует пользователей, и класс `EventEmitter`, реализующий события. Мы хотели бы добавить функционал класса `EventEmitter` к `User`, чтобы пользователи могли легко генерировать события.
Это не наследование, а просто копирование методов. Таким образом, класс `User` может расширять другие классы, но при этом также включать в себя примеси, "подмешивающие" другие методы.
50
+
Это не наследование, а просто копирование методов. Таким образом, класс `User` может наследовать от другого класса, но при этом также включать в себя примеси, "подмешивающие" другие методы.
В примере ниже `sayHiMixin`наследуется от `sayMixin`:
64
+
В примере ниже `sayHiMixin`наследует от `sayMixin`:
65
65
66
66
```js run
67
67
let sayMixin = {
@@ -101,6 +101,7 @@ new User("Dude").sayHi(); // Hello Dude!
101
101
102
102

103
103
104
+
Так как super ищет родительские методы в `[[HomeObject]].[[Prototype]]`, это означает `sayHiMixin.[[Prototype]]`, а не `User.[[Prototype]]`.
104
105
Это связано с тем, что методы `sayHi` и `sayBye` были изначально созданы в объекте `sayHiMixin`. Так что их внутреннее свойство `[[HomeObject]]` ссылается на `sayHiMixin`, как показано на картинке выше.
105
106
106
107
Вызов `super` ищет родительские методы в `[[HomeObject]].__proto__`, что означает `sayHiMixin.__proto__`, а не `User.__proto__`.
@@ -109,17 +110,17 @@ new User("Dude").sayHi(); // Hello Dude!
109
110
110
111
А сейчас давайте создадим примесь, полезную в реальной жизни.
111
112
112
-
Многие объекты в браузерной разработке (и не только) обладают важной способностью - они могут работать с событиями. События - это способ передачи информации всем, кто в ней заинтересован. Давайте создадим примесь, которая позволит легко добавлять функционал по работе с событиями любым классам/объектам.
113
+
Многие объекты в браузерной разработке (и не только) обладают важной способностью - они могут генерировать события. События - отличный способ передачи информации всем, кто в ней заинтересован. Давайте создадим примесь, которая позволит легко добавлять функционал по работе с событиями любым классам/объектам.
113
114
114
-
- Примесь добавит метод `.trigger(name, [data])` для генерации события. Аргумент `name` - это имя события, за которым следует опциональный аргумент `data`.
115
-
- Также будет добавлен метод `.on(name, handler)`, который назначает обработчик для события с заданным именем. Обработчик будет вызван, когда событие произойдёт.
115
+
- Примесь добавит метод `.trigger(name, [data])` для генерации события. Аргумент `name` - это имя события, за которым могут следовать другие аргументы с данными для события.
116
+
- Также будет добавлен метод `.on(name, handler)`, который назначает обработчик для события с заданным именем. Обработчик будет вызван, когда произойдёт событие с указанным именем `name`, и получит данные из `.trigger`.
116
117
- ...и метод `.off(name, handler)`, который удаляет обработчик указанного события.
117
118
118
-
После того, как все методы примеси будут добавлены, объект `user` сможет сгенерировать событие `"login"` после входа пользователя в личный кабинет. Объект `calendar`тоже может рассчитывать на событие`"login"`, чтобы показывать зашедшему пользователю актуальный для него календарь.
119
+
После того, как все методы примеси будут добавлены, объект `user` сможет сгенерировать событие `"login"` после входа пользователя в личный кабинет. А другой объект, к примеру, `calendar`сможет использовать это событие, чтобы показывать зашедшему пользователю актуальный для него календарь.
119
120
120
-
Или `menu` может генерировать событие `"select"`, когда элемент меню выбран, а другие объекты могут захотеть получить эту информацию и тоже отреагировать на это событие.
121
+
Или `menu` может генерировать событие `"select"`, когда элемент меню выбран, а другие объекты могут назначать обработчики, чтобы реагировать на это событие, и т.п.
121
122
122
-
Рассмотрим это всё на примере:
123
+
Вот код примеси:
123
124
124
125
```js run
125
126
let eventMixin = {
@@ -170,7 +171,7 @@ let eventMixin = {
170
171
171
172
2.`.off(eventName, handler)` -- убирает функцию из списка обработчиков.
172
173
173
-
3.`.trigger(eventName, ...args)` -- генерирует событие: все назначенные обработчики из `_eventHandlers[eventName]` вызываются, и `args`передаётся им в качестве аргумента.
174
+
3.`.trigger(eventName, ...args)` -- генерирует событие: все назначенные обработчики из `_eventHandlers[eventName]` вызываются, и `...args`передаются им в качестве аргументов.
174
175
175
176
Использование:
176
177
@@ -181,23 +182,23 @@ class Menu {
181
182
this.trigger("select", value);
182
183
}
183
184
}
184
-
// Добавим примесь
185
+
// Добавим примесь с методами для событий
185
186
Object.assign(Menu.prototype, eventMixin);
186
187
187
188
let menu =newMenu();
188
189
189
-
//Вызовем обработчик на событие "select":
190
+
//Добавить обработчик, который будет вызван при событии "select":
//Запустили событие => будет показано "Выбранное значение: 123"
195
-
menu.choose("123"); //выбранное значение
195
+
//Генерирует событие => обработчик выше запускается и выводит:
196
+
menu.choose("123"); //Выбранное значение: 123
196
197
```
197
198
198
-
Если у нас есть код, заинтересованный в событии "select", то он может подписаться на него с помощью `menu.on(...)`.
199
+
Теперь если у нас есть код, заинтересованный в событии `"select"`, то он может слушать его с помощью `menu.on(...)`.
199
200
200
-
И`eventMixin` позволяет легко добавить такое поведение в любой класс без вмешательства в цепочку наследования.
201
+
А`eventMixin` позволяет легко добавить такое поведение в любой класс без вмешательства в цепочку наследования.
201
202
202
203
## Итого
203
204
@@ -207,4 +208,4 @@ menu.choose("123"); // выбранное значение
207
208
208
209
Мы можем использовать примеси для расширения функционала классов, например, для обработки событий, как мы сделали это выше.
209
210
210
-
С примесями могут возникнуть проблемы, если они перезаписывают нативные методы класса. Стоит помнить об этом и быть внимательнее при выборе имён методов для примеси, чтобы избежать конфликтов и ошибок.
211
+
С примесями могут возникнуть проблемы, если они перезаписывают существующие методы класса. Стоит помнить об этом и быть внимательнее при выборе имён для методов примеси, чтобы избежать конфликтов.
0 commit comments