在ES6中包装类函数并使用super的简单方法

时间:2016-08-25 17:53:28

标签: javascript ecmascript-6 babeljs

我正在ES6中编写应用程序并使用babel进行转换。我有一系列形状的对象(方形,矩形,梯形等)

我希望能够将这些对象中的一些作为“特殊”对象,例如,具有双边框或圆角。但我不想将每个对象子类化(即DoubleBorderRectangle,DoubleBorderSquare)

这似乎是介绍装饰者的好地方。

但是,当我想装饰一个使用super的方法时,我遇到了问题。

例如,我有一个这样的课程:

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

一个问题是,巴贝尔不喜欢课外超级使用。这是可以理解的。有没有办法获得形状的超类并传递正确的上下文而不创建一次性对象?

1 个答案:

答案 0 :(得分:1)

我知道这已经过时但你可以实现多种方式,因此它可以归结为样式和代码行。

1)在超类中创建一个函数来添加双轮廓,假设它将由多个子类使用。

2)创建一个装饰器函数数组(超类或特定子类),然后在draw(super或sub)中检查这些函数并应用。

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

根据您的使用情况,第一个是更清洁的OOP,第二个是更多的组合功能倾向。