如何更改javascript属性调用的范围/上下文?

时间:2015-03-08 05:35:06

标签: javascript prototypal-inheritance

我认为用一个简单的例子来解释我的问题是最容易的。

想象一下,存在一个简单的Javascript类层次结构,涉及Shape和Square,其中Square'从Shape继承'。此外,在这种情况下,Shape有一个名为'color'的属性(在Shape原型上使用Object.defineProperty创建的实际属性)和一个名为'draw'的函数。此外,在此示例中,Shape类具有名为“alpha”的成员变量,该变量在Shape构造函数中初始化。还假设通过Square构造函数调用Shape构造函数。

在这种情况下假设Shape的绘制函数定义为:

Shape.prototype.draw = function(canvas) {
   alpha = 52;
   // do some stuff
};

然后使用Square覆盖并调用父(Shape)绘制函数是微不足道的:

Square.prototype.draw = function(canvas) {

  // Do some stuff here

  Shape.prototype.draw.call(this, canvas);
};

但是,我似乎无法弄清楚如何对'color'属性做同样的事情,因为我无法弄清楚如何将setter调用的范围/上下文更改为Square的实例(即'这个')。例如,如果我尝试:

Object.defineProperty(Square.prototype, "colour", {
    set : function(value) {
        // Do some stuff    
        Shape.prototype.colour = 55;
    }
});

然后,如果Shape的颜色设定器方法试图访问“alpha”,那么这当然会失败,因为'alpha'是在Square对象实例中定义的,而不是在Shape原型中定义的。 理想情况下,我希望能够做到这样的事情:

Object.defineProperty(Square.prototype, "colour", {
    set : function(value) {
        // Do some stuff    

        // Imagine that 'call_set' is a function like call, only for property setters.
        Shape.prototype.colour.call_set(this, 55);

    }
});

不幸的是AFAIK,没有像'call_set'这样的JS方法。

是否有可能以某种方式使用任意范围调用属性getter / setter?

在这个例子中假设Shape的实现是“一成不变的”,不能改变。因此,遗憾的是,“请勿使用属性”这样的答案无法解决此问题。

1 个答案:

答案 0 :(得分:0)

好的,所以我找到了答案,并认为我应该发布它以防其他人有问题。

所以我想出的解决方案是:

Object.defineProperty(Square.prototype, "colour", {
    set : function(value) {
        // Do some stuff    
        var parentProp = Object.getOwnPropertyDescriptor(Shape.prototype, "colour");
        parentProp.set.call(this, value);
    }
});

解决问题的关键在于知道如何访问“获取”问题。和'设置'财产的方法。 如果有人有更好或更有说服力的解决方案,请分享:)