如何将调用的 scope/context 更改为 javascript 属性?
How can I change the scope/context of a call to a javascript property?
我认为用一个简单的例子来解释我的问题是最容易的。
假设存在一个简单的 Javascript class 层次结构,涉及 classes Shape 和 Square,其中 Square 'inherits' 来自 Shape。此外,在这种情况下,Shape 有一个名为 'colour' 的 属性(在 Shape 原型上使用 Object.defineProperty 创建的实际 属性)和一个名为 'draw' 的函数。此外,在此示例中,Shape class 具有一个名为 '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);
};
但是,我似乎无法弄清楚如何对 'colour' 属性 执行相同的操作,因为我无法弄清楚如何将调用的 scope/context 更改为setter 到 Square 的实例(即 'this')。例如,如果我尝试:
Object.defineProperty(Square.prototype, "colour", {
set : function(value) {
// Do some stuff
Shape.prototype.colour = 55;
}
});
如果 Shape 的颜色 setter 方法试图访问 '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的实现是'set in stone'并且不能改变。因此,不幸的是,“不要使用属性”之类的答案无法解决此问题。
好的,所以我找到了这个问题的答案并认为我应该 post 它以防其他人遇到问题。
所以我想到的解决方案是这样的:
Object.defineProperty(Square.prototype, "colour", {
set : function(value) {
// Do some stuff
var parentProp = Object.getOwnPropertyDescriptor(Shape.prototype, "colour");
parentProp.set.call(this, value);
}
});
解决问题的关键在于知道如何访问 属性 的 'get' 和 'set' 方法。
如果有人有更好或更多 eloquent 的解决方案,请分享:)
我认为用一个简单的例子来解释我的问题是最容易的。
假设存在一个简单的 Javascript class 层次结构,涉及 classes Shape 和 Square,其中 Square 'inherits' 来自 Shape。此外,在这种情况下,Shape 有一个名为 'colour' 的 属性(在 Shape 原型上使用 Object.defineProperty 创建的实际 属性)和一个名为 'draw' 的函数。此外,在此示例中,Shape class 具有一个名为 '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);
};
但是,我似乎无法弄清楚如何对 'colour' 属性 执行相同的操作,因为我无法弄清楚如何将调用的 scope/context 更改为setter 到 Square 的实例(即 'this')。例如,如果我尝试:
Object.defineProperty(Square.prototype, "colour", {
set : function(value) {
// Do some stuff
Shape.prototype.colour = 55;
}
});
如果 Shape 的颜色 setter 方法试图访问 '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的实现是'set in stone'并且不能改变。因此,不幸的是,“不要使用属性”之类的答案无法解决此问题。
好的,所以我找到了这个问题的答案并认为我应该 post 它以防其他人遇到问题。
所以我想到的解决方案是这样的:
Object.defineProperty(Square.prototype, "colour", {
set : function(value) {
// Do some stuff
var parentProp = Object.getOwnPropertyDescriptor(Shape.prototype, "colour");
parentProp.set.call(this, value);
}
});
解决问题的关键在于知道如何访问 属性 的 'get' 和 'set' 方法。 如果有人有更好或更多 eloquent 的解决方案,请分享:)