JavaScript classes right now and hopefully also in future
only can be extended from each other but can not be mixed
into one another. If at all, then most probably Lightweight Traits
do make it into the specification one day.
Its architectural approach is specific to JavaScript. It
has been mentioned quite often in the last few years ...
esdiscuss.org: »about lightweight traits«,
github.com/WebReflection: »features :: with«,
webreflection.blogspot.com: »A future friendly, backward compatible, class utility«,
reddit.com/r/javascript: »Functional Mixins in ECMAScript 2015«,
raganwald.com: »Functional Mixins in ECMAScript 2015« ...
and possibly is best compared to Angus Croll's Flight Mixins.
Pure function based Mixin/Trait approaches ... This is not an essay about 'Traits in Javascript',
The many »Talents« of JavaScript ...
do come closest to what the OP has ask for unless something
similar to ...
// proposed trait syntax ... // ... desugared e.g. to ...
trait Enumerable_first_last { // var Enumerable_first_last = (function () {
// trait body. // // mixin module.
//
const // var
FIRST = function () { // first = function () { // shared code.
return this[0]; // return this[0];
}, // },
LAST = function () { // last = function () {
return this[this.length - 1]; // return this[this.length - 1];
} // }
; // ;
//
applicator () { // return function Enumerable_first_last () {
// applicator body. // // mixin body.
//
this.first = FIRST; // this.first = first; // referencing ...
this.last = LAST; // this.last = last; // ... shared code.
} // };
//
} // }());
...
// proposed trait syntax ... // ... desugared e.g. to ...
trait Enumerable_item { // var Enumerable_item = (function () {
//
const // var
ITEM = function (idx) { // item = function (idx) {
return this[ // return this[
Math.floor( // Math.floor(
parseFloat(idx, 10) // parseFloat(idx, 10)
) // )
]; // ];
} // }
; // ;
//
applicator () { // return function Enumerable_item () {
//
this.item = ITEM; // this.item = item;
} // };
//
} // }());
...
// proposed trait syntax ... // ... desugared e.g. to ...
trait Enumerable_first_last_item { // var Enumerable_first_last_item = (function () {
//
use Enumerable_first_last; // return function Enumerable_first_last_item() {
use Enumerable_item; //
/* // Enumerable_first_last.call(this);
applicator () { // Enumerable_item.call(this);
// can be omitted if empty. // };
}*/ //
} // }());
...
// ... desugared e.g. to ...
//
class Queue { // var Queue = (function () {
//
//use Allocable; // return function Queue () {
use Observable; // var list = [];
//
constructor () { // this.enqueue = function (type) {
const list = []; //
// list.push(type);
this.enqueue = function (type) { // return type;
// };
list.push(type); // this.dequeue = function () {
return type; //
}; // return list.shift();
this.dequeue = function () { // };
//
return list.shift(); // //Allocable.call(this, ...);
}; // Observable.call(this);
} // };
//
} // }());
//
var q = new Queue; // var q = new Queue;
//
q.enqueue(9); // q.enqueue(9);
q.enqueue(8); // q.enqueue(8);
q.enqueue(7); // q.enqueue(7);
//
console.log(q.dequeue()); // console.log(q.dequeue());
console.log(q.dequeue()); // console.log(q.dequeue());
console.log(q.dequeue()); // console.log(q.dequeue());
//
console.log(q); // console.log(q);
console.log(Object.keys(q)); // console.log(Object.keys(q));
... was shipped to ECMAScript land.