覆盖使用 Object.defineProperty 创建的 getter/setter



我遇到了一个问题,即我通过 Object.defineProperty 添加到对象的属性出现错误。

有问题的错误。

Exception: RangeError: Maximum call stack size exceeded

也许(可能(我的设计不正确,我应该做一些不同的事情。这就是我打算用下面的代码做的:

  • 通过工厂函数创建对象 P。
  • 将配置对象 C 传递给工厂以自定义 P。
  • 将 P 中的 C 存储为私有对象,并通过 Object.defineProperty 将其属性附加到 P 来获取/设置 C 的值。对于任何给定的 P,C 可能不同。
  • 当我想覆盖某些 C.a 的默认 get/set 方法时,问题就来了

我这样做如下:

// Create P with a custom (non-default) get method.
let C = { a: 1, b: 2, c: 3 };
let P = factory.createObject(C);
const customGetA = function(object, property) {
return function() {
if(!object[property])
object[property] = ' ';
return object[property];
};
};
P.customgGetMethod('a', customGetA);
// Looking at object in the console reveals the error mentioned above.

let factory = (function() {
'use strict';
this.createObject = function(config) {
const product = {};
let C = config;
// Add default getters/setters to the product, referencing the properties of C.
for (const property in config) {
Object.defineProperty(product, property, { 
get: function() { 
return C[property];
},
set: function(value) {
C[property] = value;
},
configurable: true,
enumerable: true
});
}
product.customGetMethod = function(property, callback) {
// Get the property description.
let descriptor = Object.getOwnPropertyDescriptor(this, property);
// Assign the custom get method within the callback, binding its values via closure.
descriptor.get = callback(this, property);
// Redefine the property with the new get method.
Object.defineProperty(this, property, descriptor);
};
return product;
};
})();

最后,我希望能够将自定义数据对象传递到 P 中并使其保持私有,并根据该数据动态生成 get/set 方法,这样我就不必为N属性 *M产品获取/设置样板。这可能不是最好的设计或实现,但我不知道如何以另一种方式做到这一点。

任何替代方案或见解将不胜感激。

customGetAP.customgGetMethod('a', customGetA);中创建的 getter 函数本质上是

function() {
if(!product.a)
product.a = ' ';
return product.a;
}

当我们将其与factory中创建的默认 getter 进行比较时

function() { 
return C.a;
}

我们可以看到,新的查找product中的值,而不是配置C。在product中查找属性会评估它的 getter,这是我们已经在的函数,它会递归,直到它最终溢出堆栈......

我想你正在寻找

// Assign the custom get method within the callback, binding its values via closure.
descriptor.get = callback(C, property);
//                        ^

以关闭内部配置对象。

最新更新