Photo by Stanislav Ivanitskiy on Unsplash
IIFEs, Mixins, and Modules in JavaScript Objects
Refactoring ugly code into pretty code
Wikipedia describes a mixin in general terms as so:
In object-oriented programming languages, a mixin (or mix-in) is a class that contains methods for use by other classes without having to be the parent class of those other classes.
In this particular part of OOP part of the freeCodeCamp course I am taking, they are going over IIFEs, objects, mixins, and what they call modules. One of the lessons has the student refactor two given mixins into a IIFE that returns an object--i.e. a module.
Per FCC, "The advantage of the module pattern is that all of the motion behaviors can be packaged into a single object that can then be used by other parts of your code."
Note: The focus of this post is not IIFEs (though they are interesting!)
Non-module mixins
This is the code provided by FCC in their lesson. The intent of the lesson is to have the student refactor the below mixins into an IIFE that returns an object of mixins.
// Provided by FCC
let isCuteMixin = function(obj) {
obj.isCute = function() {
return true;
};
};
let singMixin = function(obj) {
obj.sing = function() {
console.log("Singing to an awesome tune");
};
};
Mixins, modularized (via function declarations)
Below is one version of the code that passes their refactorization challenge. It uses function declarations. It is largely based on an example provided by FCC in their lesson.
It is objectively ugly
It is overly verbose
Note how the top-level
return
returns an object.
let funModule = (function () {
return {
isCuteMixin: function(obj) {
obj.isCute = function() {
return true;
};
},
singMixin: function(obj) {
obj.sing = function() {
console.log("Singing to an awesome tune");
};
}
}
})();
Mixins, modularized! (via ES6 arrow functions)
The below code is the code above, just further refactored to remove all function declarations. This code also passes their refactorization challenge.
It uses ES6 arrow functions and implicit return where appropriate.
It is not ugly
It is more concise
let funModule = (() => {
return {
isCuteMixin: obj => {
obj.isCute = () => true;
},
singMixin: obj => {
obj.sing = () => console.log("Singing to an awesome tune");
}
}
})();
Important differences
In both refactorizations, important differences are as follows:
The comma between
isCuteMixin
andsingMixin
as methodsThe
:
instead of the=
as to defining the methods' logicThe lack of
let
as to bothisCuteMixin
andsingMixin
Seeing them side by side as a diffing is probably most helpful!