JavaScript ES6 Multiple Inheritance Class
Adds functionality to ES6 for multi inheritance of classes.
Introduction
I decided to jump into JavaScript ES6 and start learning the new features. I like everything except the lack of multiple inheritance support for classes. Having to chain around single classes to make multi inheritance is a pain in the ass. So in an attempt to resolve the problem, I came up with the class below.
Multi Inheritance Class
// Class for creating multi inheritance.
class multi
{
// Inherit method to create base classes.
static inherit(..._bases)
{
class classes {
// The base classes
get base() { return _bases; }
constructor(..._args)
{
var index = 0;
for (let b of this.base)
{
let obj = new b(_args[index++]);
multi.copy(this, obj);
}
}
}
// Copy over properties and methods
for (let base of _bases)
{
multi.copy(classes, base);
multi.copy(classes.prototype, base.prototype);
}
return classes;
}
// Copies the properties from one class to another
static copy(_target, _source)
{
for (let key of Reflect.ownKeys(_source))
{
if (key !== "constructor" && key !== "prototype" && key !== "name")
{
let desc = Object.getOwnPropertyDescriptor(_source, key);
Object.defineProperty(_target, key, desc);
}
}
}
}
How Does it Work?
In order for multi inheritance to work, I utilized a lot of the new ES6 features in combination with ES5. The class is extended by using the following code.
// Single Inherit
class person extends ages
// Multi Inherit
class person extends multi.inherit(ages, genders)
Instead of passing a class to the extend, we pass a static function called inherit, which returns a class after merging properties and methods together of other named classes. Inside the inherit method, we receive a rest parameter with all class names to inherit from.
// The base classes
get base() { return _bases; }
This is a key feature for creating the instances of each class and copying their properties in the constructor method. We forward the parameters from the super() to the constructor.
constructor(..._args)
{
var index = 0;
for (let b of this.base)
{
let obj = new b(_args[index++]);
multi.copy(this, obj);
}
}
Below is a full working example of multiple inheritance.
Full Sample Code
// Class for creating multi inheritance.
class multi
{
// Inherit method to create base classes.
static inherit(..._bases)
{
class classes {
// The base classes
get base() { return _bases; }
constructor(..._args)
{
var index = 0;
for (let b of this.base)
{
let obj = new b(_args[index++]);
multi.copy(this, obj);
}
}
}
// Copy over properties and methods
for (let base of _bases)
{
multi.copy(classes, base);
multi.copy(classes.prototype, base.prototype);
}
return classes;
}
// Copies the properties from one class to another
static copy(_target, _source)
{
for (let key of Reflect.ownKeys(_source))
{
if (key !== "constructor" && key !== "prototype" && key !== "name")
{
let desc = Object.getOwnPropertyDescriptor(_source, key);
Object.defineProperty(_target, key, desc);
}
}
}
}
class ages
{
constructor(_age) { this.age = _age; }
set age(_a) { this._age = _a; }
get age() { return this._age; }
increase() { this.age++; }
}
class genders
{
constructor(_gender) { this.gender = _gender; }
set gender(_g) { this._gender = _g; }
get gender() { return this._gender; }
male() { this._gender = 'M'; }
female() { this._gender = 'F'; }
}
class person extends multi.inherit(ages, genders)
{
constructor(...args)
{
super(18, 'M');
this.name = args[0];
}
set name(_n) { this._name = _n; }
get name() { return this._name; }
}
var p = new person('Adam');
console.log(p.name, p.age, p.gender);
History
Version 0.1 - First release of script, needs perfecting.