在构建API polyfill的过程中,我想覆盖具有getter和setter的元素的属性(在本例中为width和height)以捕获对值的更改并在将其传递给底层元素之前对其进行修改。理想情况下,这个过程也是可逆的。这段代码的内容:
var realWidth = null;
function patch(targetObject) {
realWidth = targetObject.magicalPropertyAccessor("width");
Object.defineProperty(targetObject, 'width', {
get: function() {
return realWidth / 2;
},
set: function(value) {
realWidth = value * 2;
}
});
}
function unpatch(targetObject) {
if (realWidth)
targetObject.magicalPropertySetter('width', realWidth);
}
示例的意图是,当元素被修补时,它会默默地将对其维度的更改加倍,同时报告原始的未更改的值。如果这是一个函数,它将非常简单,但作为一个属性,不清楚如何缓存对原始访问器的引用。
答案 0 :(得分:0)
感谢Bergi,我发现Object.getOwnPropertyDescriptor
正是我想要的。我曾经尝试过,但错过了我必须去对象的__proto__
寻找我正在寻找的房产的财产。 (您的milage可能会因您要替换的属性而异。)这是适用于我的代码:
function WidthPatch(canvas) {
var self = this;
var fakeWidth = canvas.width;
this.canvas = canvas;
// Cache the real property
this.realWidthProp = Object.getOwnPropertyDescriptor(canvas.__proto__, 'width');
// Replace the property with a custom one
Object.defineProperty(canvas, 'width', {
configurable: true,
enumerable: true,
get: function() {
return fakeWidth;
},
set: function(value) {
fakeWidth = value;
// This updates the real canvas property, silently doubling it.
self.realWidthProp.set.call(canvas, fakeWidth * 2);
}
});
}
WidthPatch.prototype.unpatch = function() {
// Replace the custom property with the original one.
Object.defineProperty(this.canvas, 'width', this.realWidthProp);
}