После классического (от слова class) наследования в JS стало так все чисто , я решил изучить реализацию другого способа повторного использования кода — миксинов.
Несмотря на довольно необычное название, этот метод чертовски прост.
1. Примеси – что это такое?
Миксин — это объект с набором функций, который не используется сам по себе (отдельно от других объектов).Вот, например, замечательный миксин:
Когда мы попытаемся вызвать метод Say просто так, нас ждет облом, потому что ни это имя , ни один это.var Mixin_Babbler = { say: function () { console.log("My name is " + this.name + " and i think:'" + this.THOUGHTS + "'"); }, argue: function() { console.log("You're totally wrong"); } };
МЫСЛИ в нашем учреждении его почему-то просто нет.
На самом деле все правильно, чтобы использовать миксин по прямому назначению, нам нужен еще один объект, и метод, который копирует все свойства переданных ему объектов миксина в прототип функции-конструктора - обычно этот метод называется расширением, или миксом, или чем-то в этом роде: function extend(object)
{
var mixins = Array.prototype.slice.call(arguments, 1);
for (var i = 0; i < mixins.length; ++i)
{
for (var prop in mixins[i])
{
if (typeof object.prototype[prop] === "undefined")
{
object.prototype[prop] = mixins[i][prop];
}
}
}
}
2. Так как же его использовать?
Легко и не напрягаясь – допустим, у нас есть парочка примесей: var Mixin_Babbler =
{
say: function () { console.log("My name is " + this.name + " and i think:'" + this.THOUGHTS + "'"); },
argue: function() { console.log("You're totally wrong"); }
};
var Mixin_BeverageLover =
{
drink: function () { console.log("* drinking " + this.FAVORITE_BEVERAGE + " *"); }
};
И, к некоторой, возможно уже знакомой, эволюционной цепочке:
function Man(name)
{
this.name = name;
}
Man.prototype =
{
constructor: Man,
THOUGHTS: "I like soccer"
}
extend(Man, Mixin_Babbler);
function Gentleman(name)
{
this.name = name;
}
Gentleman.prototype =
{
constructor: Gentleman,
THOUGHTS: "I like Earl Grey",
FAVORITE_BEVERAGE: "Tea"
}
extend(Gentleman, Mixin_Babbler, Mixin_BeverageLover);
function Programmer(name)
{
this.name = name;
}
Programmer.prototype =
{
constructor: Programmer,
THOUGHTS: "MVC, MVVM, MVP *___* like it!",
FAVORITE_BEVERAGE: "Cofee",
write_good_code: function () { console.log("*writing best code ever*"); this.drink(); }
}
extend(Programmer, Mixin_Babbler, Mixin_BeverageLover);
Каждый «класс» теперь независим от другого, а вся повторяющаяся функциональность реализована с помощью примесей.
Теперь стоит все проверить — вдруг заработает: var man = new Man("Bob");
var gentleman = new Gentleman("Bill");
var programmer = new Programmer("Benjamin");
man.say();
man.argue();
gentleman.say();
gentleman.drink();
programmer.say();
programmer.write_good_code();
А в консоли написано, что да, все так и должно быть: My name is Bob and i think:'I like soccer'
*You're totally wrong*
My name is Bill and i think:'I like Earl Grey'
*drinking Tea*
My name is Benjamin and i think:'MVC, MVVM, MVP like *__* it!'
*writing best code ever*
*drinking Cofee*
Вот и все.
В отличие от «классического» наследования, реализация миксинов очень проста и понятна.
Есть, конечно, некоторые вариации, но ядро в любом случае выглядит так.
УПД.
Как подсказал один очень хороший человек с ником: лалаки , метод расширения можно реализовать немного иначе: function extend_2(object)
{
var mixins = Array.prototype.slice.call(arguments, 1);
for (var i = 0; i < mixins.length; ++i)
{
for (var prop in mixins[i])
{
if (typeof object.prototype[prop] === "undefined")
{
bindMethod = function (mixin, prop)
{
return function () { mixin[prop].
apply(this, arguments) }
}
object.prototype[prop] = bindMethod(mixins[i], prop);
}
}
}
}
При таком подходе вы можете на лету менять методы в миксине, и эти изменения сразу же будут доступны всем объектам, использующим этот миксин.
Очень и очень маленький недостаток заключается в том, что не очень умная подсказка в среде разработки всегда будет показывать, что у методов нет аргументов.
Весь код и примеры лежат спокойно Прямо здесь Теги: #JavaScript #наследование #Mixin #JavaScript
-
Автоматизация Лестничного Освещения
19 Oct, 24 -
Машинное Обучение – 4: Скользящее Среднее
19 Oct, 24 -
Трагедия 100% Покрытия Кода
19 Oct, 24