# Примеси В JavaScript невозможно унаследовать от двух и более объектов. Ссылка `__proto__` -- только одна. Но потребность такая существует -- к примеру, мы написали код, релизующий методы работы с шаблонизатором или методы по обмену событиями, и хочется легко и непринуждённо добавлять эти возможности к любому классу. Обычно это делают через примеси. Примесь (англ. mixin) -- класс или объект, реализующий какое-либо чётко выделенное поведение. Используется для уточнения поведения других классов, не предназначен для самостоятельного использования. ## Пример примеси Самый простой вариант примеси -- это объект с полезными методами, которые мы просто копируем в нужный прототип. Например: ```js run *!* // примесь */!* var sayHiMixin = { sayHi: function() { alert("Привет " + this.name); }, sayBye: function() { alert("Пока " + this.name); } }; *!* // использование: */!* function User(name) { this.name = name; } // передать методы примеси for(var key in sayHiMixin) User.prototype[key] = sayHiMixin[key]; // User "умеет" sayHi new User("Вася").sayHi(); // Привет Вася ``` Как видно из примера, методы примеси активно используют `this` и предназначены именно для запуска в контексте "объекта-носителя примеси". Если какие-то из методов примеси не нужны -- их можно перезаписать своими после копирования. ## Примесь для событий Теперь пример из реальной жизни. Важный аспект, который может понадобиться объектам -- это умение работать с событиями. То есть, чтобы объект мог специальным вызовом генерировать "уведомление о событии", а на эти уведомления другие объекты могли "подписываться", чтобы их получать. Например, объект "Пользователь" при входе на сайт может генерировать событие `"login"`, а другие объекты, например "Календарь" может такие уведомления получать и подгружать информацию о пользователе. Или объект "Меню" может при выборе пункта меню генерировать событие `"select"` с информацией о выбранном пункте меню, а другие объекты -- подписавшись на это событие, будут узнавать об этом. События -- это средство "поделиться информацией" с неопределённым кругом заинтересованных лиц. А там уже кому надо -- тот среагирует. Примесь `eventMixin`, реализующая события: ```js var eventMixin = { /** * Подписка на событие * Использование: * menu.on('select', function(item) { ... } */ on: function(eventName, handler) { if (!this._eventHandlers) this._eventHandlers = {}; if (!this._eventHandlers[eventName]) { this._eventHandlers[eventName] = []; } this._eventHandlers[eventName].push(handler); }, /** * Прекращение подписки * menu.off('select', handler) */ off: function(eventName, handler) { var handlers = this._eventHandlers && this._eventHandlers[eventName]; if (!handlers) return; for(var i=0; i