2016-08-16 3 views
0

Я придумываю архитектуру View (HTML markup) и Utility (JavaScript - поведение) и создаю атомные классы для составления представлений и утилит с использованием класса ES6. Будет необходимо, чтобы несколько классов полезности могли быть составлены/объединены в один класс представления.ES 6 Классы - Mixins

Как API-интерфейс ES6 предоставляет способ смешивания класса (ов) в другой/основной класс. Я просмотрел Object.assign, но это касается объектов, а не класса.

ответ

2

JavaScript-классы прямо сейчас и, надеюсь, также в будущем могут быть расширены друг от друга, но не могут быть смешаны друг с другом. Если вообще, то, скорее всего, Легкие черты сделайте это в спецификации один день.

Его архитектурный подход специфичен для JavaScript. Это было упомянуто довольно часто в последние несколько лет ... 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« ... и, возможно, лучше всего по сравнению с Flight Mixins Ангусом Кроллом.

Чистая функция, основанная Mixin/Тре подходы ... This is not an essay about 'Traits in Javascript', The many »Talents« of JavaScript ... приходят ближе к тому, что ОП уже просят, если что-то похож на ...

// 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)); 

... был отправлен в ECMAScript земли.

+0

1/2 - для того, чтобы доказать выше эскизного черта синтаксиса я предоставил LIB и иллюстративно сделал реорганизовать код 4 других Trait связанных JavaScript Qs, который тоже ара (1) [Com (http://stackoverflow.com/questions/41999608/compostions-and-mixins-in-js/43141778#43141778), (2) [Микшины для классов ES6, переполненные babel] (http: //stackoverflow.com/questions/30732241/mixins-for-es6-classes-transpiled-with-babel/43129978#43129978), ... –

+0

2/2 - (3) [Рефакторинг устаревших иерархий классов на основе микшинга] (http://stackoverflow.com/questions/43027388/refactoring-legacy-mixin-based-class-hierarchies/43059101#43059101) и (4) [Множественное наследование с использованием классов] (http://stackoverflow.com/questions/41918874/multiple-inheritance-using-classes/43748183#43748183). –

2

Существует действительно хороший шаблон с ES2015 классами (который я не обязательно одобряю как таковой) для создания mixins by Sebastian Markbage, который я слегка адаптировал.

Функция полезности mixinClasses может использоваться для смешивания в классе заводов (ака фабричные функции, которые возвращают классы) в новый класс:

function mixinClasses(...mixins) { 
    // TODO: Add all possible method names that might call super() 
    // to the base class so that they don't throw. 
    return mixins.reduce((base, mixin) => { 
     return mixin(base); 
    }, class {}); 
} 

, который можно использовать следующим образом, например, с двумя заводскими функциями Foo и Bar:

const Foo = base => class extends base { 
    myFn() { 
    } 
}; 

const Bar = base => class extends base { 
    myFn() { 
    super.myFn(); 
    } 
}; 

class Baz extends mixinClasses(Foo, Bar) { 
    myFn() { 
    super.myFn(); 
    } 
} 
Смежные вопросы