簡體   English   中英

是否有一種不那么麻煩的方法來檢索原型鏈中某處的 getter 和 setter 方法?

[英]Is there a less cumbersome method of retrieving getter and setter methods that are somewhere in the prototype chain?

我有一個對象的引用,該對象在其原型鏈中的某處具有某個屬性的 getter 和 setter。 我想獲得對 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循環很丑陋 當然,可以使用當前對象的調用上下文調用getter和setter,代碼非常簡單,如

obj2.prop = 'newVal';   // invoke setter
const val = obj2.prop;  // invoke getter

但這會調用函數而無法與它們(或它們所在的原型對象)進行交互。

有沒有更清晰、更短的方法來實現我在上面的代碼片段中所做的事情?

這看起來很麻煩,而且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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM