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

How can I change the scope/context of a call to a javascript property?

本文关键字:调用 范围 上下文 属性 何更改 javascript      更新时间:2023-09-26

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

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

在此方案中,假设 Shape 的绘制函数定义为:

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

然后,具有方形覆盖并调用父(形状)绘制函数是微不足道的:

Square.prototype.draw = function(canvas) {
  // Do some stuff here
  Shape.prototype.draw.call(this, canvas);
};

但是,我似乎无法弄清楚如何对"color"属性做同样的事情,因为我无法弄清楚如何将对 Square 实例的调用的范围/上下文更改为 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方法。

是否可以使用任意范围以某种方式调用属性获取器/设置器?

在此示例中,假设 Shape 的实现是"一成不变的",无法更改。因此,不幸的是,诸如"不使用属性"之类的答案将无法解决此问题。

好的,

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

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

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

解决问题的关键在于知道如何访问属性的"获取"和"设置"方法。如果有人有任何更好或更有说服力的解决方案,那么请分享:)