我有一个对象的引用,该对象在其原型链中某处具有某种属性的吸气剂和吸气剂。我想获得对getter和setter方法以及它们所在的对象的引用。我知道我可以通过手动遍历每个原型对象并检查hasOwnProperty
来做到这一点,如以下代码片段所示:
const obj2 = (() => {
const baseProto = {
get prop() {
return 'propval';
},
set prop(newVal) {
console.log('setting...');
}
};
const obj1 = Object.create(baseProto);
return Object.create(obj1);
})();
// From having a reference to obj2, want to get the getter or setter methods,
// and want to get the object they're on, without invoking them:
let currentObj = obj2;
const propToFind = 'prop';
let get, set, foundProto;
while (currentObj) {
if (currentObj.hasOwnProperty(propToFind)) {
foundProto = currentObj;
({ get, set } = Object.getOwnPropertyDescriptor(currentObj, propToFind));
break;
}
currentObj = Object.getPrototypeOf(currentObj);
}
if (foundProto) {
console.log('Found:', get, set, foundProto);
}
这似乎很麻烦,while
循环很丑陋。当然,可以使用当前对象的调用上下文,通过非常简单的代码(如
obj2.prop = 'newVal'; // invoke setter
const val = obj2.prop; // invoke getter
但是这会调用功能而不能够与它们(或它们所在的原型对象)进行交互。
在上面的代码段中,有没有更清晰,更短的方法来实现我的目的?
答案 0 :(得分:1)
这似乎很麻烦,
while
循环很丑陋
我不认为这很麻烦,这只是您尝试在原型链上任何位置查找属性时要做的事情。
您当然不必编写while
循环,迭代可以很容易地表示为for
循环:
let get, set, foundProto;
for (let currentObj = obj2; currentObj; currentObj = Object.getPrototypeOf(currentObj)) {
if (currentObj.hasOwnProperty('prop')) {
foundProto = currentObj;
({ get, set } = Object.getOwnPropertyDescriptor(currentObj, 'prop'));
break;
}
}
if (foundProto) {
console.log('Found:', get, set, foundProto);
}
您当然也可以编写一个辅助函数来做到这一点,例如
function getInheritedPropertyDescriptor(obj, prop) {
for (; obj != null; obj = Object.getPrototypeOf(obj)) {
if (Object.prototype.hasOwnProperty.call(obj, prop)) {
return { foundProto: obj, ...Object.getOwnPropertyDescriptor(obj, prop) };
}
}
return null;
}
var result = getInheritedPropertyDescriptor(obj2, 'prop');
if (result) {
console.log('Found:', result.get, result.set, result.foundProto);
}