Introduction
Throughout all the blog posts on my blog, we have realized that prototypical inheritance works reasonably well in JavaScript. We do know; however, there is only one [[Prototype]] for each object. It means that an object can only inherit from one other object. The same goes for classes as we can only extend from one other class. JavaScript doesn't support multiple inheritance.
A mixin could is a class that has methods which we can use in our class without inheriting from the mixin class. It is a way of adding properties to object without using inheritance.
In theory, it would look something like this.
- Inheritance in classes
class B extends A {}
- Inheritance but with Mixin (M1)
class B extends A with M1 {}
- Inheritance with multiple Mixins (M1, M2, M3)
class B extends A with M1, M2, M3 {}
The complete secret sauce of mixins is in Object.assign
!
Implementation
For Objects
cconst employee = {
name: "John Smith",
age: 30,
gender: "male"
}
const payroll = {
duration: "monthly",
amount: 7000,
currency: "dollars"
}
const benefits = {
retirement: true,
savings: true,
health: true,
dental: false
}
const employeeProfile = Object.assign({}, employee, payroll, benefits);
console.log(employeeProfile);
The output on the console will be:
{ name: 'John Smith',
age: 30,
gender: 'male',
duration: 'monthly',
amount: 7000,
currency: 'dollars',
retirement: true,
savings: true,
health: true,
dental: false }
Yes, this is what a mixin does. It allows us to combine the properties of different objects into a single object (in simplest terms). The Object.assign
copies all enumerable properties from one or more source objects to a target object. The first argument is the target object, followed by all source object(s).
For Classes
let employeeDetails = {
returnName() {
console.log(`The employee is ${this.name}`);
},
subscribesToDental () {
console.log(`Employee ${this.name} does ${(this.dental) ? "" : "not "}subscribe to dental benefits`);
}
};
class Employee {
name;
dental;
constructor(name, dental) {
this.name = name;
this.dental = dental;
}
}
Object.assign(Employee.prototype, employeeDetails);
new Employee("Parwinder", false).returnName();
// The employee is Parwinder
new Employee("Parwinder", false).subscribesToDental();
// Employee Parwinder does not subscribe to dental benefits
new Employee("Robert", true).subscribesToDental();
// Employee Robert does subscribe to dental benefits
π¨ Javascript supports the use of super
keyword now. Mixins are not able to support super
as it is lexically bound!
Top comments (7)
Hey there, I'm a little confused about this article. Are Mixins a real thing? Are they an idea you're presenting? Are they something upcoming in the JS spec?
Hey Jared,
Great question and thanks for reading. Mixins are definitely real. There are times when youβd want to inherit from multiple classes or objects.
That being said there is no official way of implementing Mixins with JS. The lack of true inheritance or composition does lead to myriad of implementation techniques.
Would you ever need it? Maybe not.
Adding object oriented principles to JavaScript might not be fruitful in my opinion but I do bring them up for awareness.
What do you think about 'stamp' ? medium.com/javascript-scene/introd...
Thanks a ton! As much time as I spend with JavaScript, I am surprised I had not heard of this. That means I have no opinion on it.. yet.
This gives me something new to learn over the next week or two. I appreciate that you brought it up.
A mixin is a class containing methods that can be used by other classes without a need to inherit from it. In other words, a mixin provides methods that implement a certain behavior, but we do not use it alone, we use it to add the behavior to other classes. It just shows that class based inheritance is not as flexible prototypal inheritance.
Just one note... The MDN killed the "with" statement, but I am sure you already figured this out. I would update this article if you have the time. Great Article... developer.mozilla.org/en-US/docs/W...
Thanks , you made it way simple for me understand :)