2016-08-25 2 views
0

Я пишу приложение в ES6 и транслирую с помощью babel. У меня есть ряд объектов, которые являются формами (Квадрат, Прямоугольник, Трапеция и т. Д.)Простой способ обернуть функцию класса и использовать супер в ES6

Я хочу, чтобы некоторые из этих объектов «специальные» объекты, например, имели двойную границу или закругленные углы , Но я не хочу подклассифицировать каждый объект (т. Е. DoubleBorderRectangle, DoubleBorderSquare)

Это кажется хорошим местом для размещения декоратора.

У меня возникают проблемы, однако, когда я хочу украсить метод, который использует супер.

Например, у меня есть класс, как это:

class Trapezoid extends Sprite { 
    constructor(x, y, width, height) { 
     super(x, y, width, height); 
     this.type = "Trapezoid"; 
     //other trapezoid specific functions here. 
    } 
    draw(ctx) { 
     super.draw(ctx); 
     //specific code for drawing trapezoid here. 
    } 
} 

Теперь я хочу, чтобы иметь возможность создать экземпляр специальной трапеции, скажем, с двойной рамкой, используя декоратор:

function doubleBorder(shape) { 

    shape.draw = function(ctx) { 

     //draw the trapezoid. 
     super.draw(ctx); 

     //double border drawing stuff here. 
    } 

    return shape; 
} 

И экземпляр:

let trapezoid = new Trapezoid(0,0,100,100); 
let doubleBorderTrapezoid = doubleBorder(trapezoid); 

Одна из проблем заключается в том, что Babel не любит супер, используемую за пределами класса. Что понятно. Есть ли способ завладеть суперклассом формы и передать ему правильный контекст, не создавая лишний объект?

ответ

1

Я знаю, что это старо, но вы можете реализовать множество способов, так что это сводится к стилю и строкам кода.

1) Создайте функцию в суперклассе, чтобы добавить двойной контур, предполагает, что это будет использоваться несколькими подклассами.

2) Создайте массив функций декоратора (суперкласс или определенный подкласс), затем проверьте их в draw (super или sub) и примените.

const myDecorator = (ctx) => { ... } ... draw(ctx) { this.decorators.forEach(draw => draw(ctx)); }

В зависимости от вашего использования случае первый является более чистым OOP, то второй более функциональный состав падающим.

Смежные вопросы