我试图在打字稿中发现对象上的 getter 和 setter。我尝试过 Object.entries() 和 Object.keys() ,但这些都没有返回 getter 和 setter。我怎样才能列举这些呢?
编辑:这是一些显示问题的代码:
class ThingWithGetter{
myProperty = 22;
get myGetter() {return 1;}
}
const thing = new ThingWithGetter()
// Does not show getter
console.log(Object.keys(thing));
// Does not show getter
const descriptors = Object.getOwnPropertyDescriptors(thing);
console.log(Object.keys(descriptors));
// Does not show getter
console.log(Object.entries(thing))
Run Code Online (Sandbox Code Playgroud)
您可以使用此函数枚举 getter 名称:
function listGetters (instance) {
return Object.entries(
Object.getOwnPropertyDescriptors(
Reflect.getPrototypeOf(instance)
)
)
.filter(e => typeof e[1].get === 'function' && e[0] !== '__proto__')
.map(e => e[0]);
}
Run Code Online (Sandbox Code Playgroud)
它将返回一个包含 getter 名称的数组。
这不起作用的原因是 getter 位于类的原型上,该原型位于实例的原型链上,而不是实例本身。
为了显示:
class A {
get x() { return 1 }
}
aInstance = new A()
// A {}
Object.getOwnPropertyDescriptors(aInstance)
// {}
Object.getOwnPropertyDescriptors(A.prototype)
// { constructor:
// { value: [Function: A],
// writable: true,
// enumerable: false,
// configurable: true },
// x:
// { get: [Function: get x],
// set: undefined,
// enumerable: false,
// configurable: true } }
Object.getOwnPropertyDescriptors(Object.getPrototypeOf(aInstance))
// { constructor:
// { value: [Function: A],
// writable: true,
// enumerable: false,
// configurable: true },
// x:
// { get: [Function: get x],
// set: undefined,
// enumerable: false,
// configurable: true } }
Run Code Online (Sandbox Code Playgroud)
Axel Rauschmayer 关于这个主题有一些很好的博客文章:
请注意,如果您尝试枚举对象上的所有属性、访问器和方法,则需要递归地遍历原型链,直到对象具有原型null。
该函数Object.getOwnPropertyDescriptors位于 ECMAScript 最新草案规范中,但在流行的浏览器中实现。它返回属于对象的属性描述符。
您的用例有点困难,因为 getter 是在类上定义的,而不是对象本身。因此,您需要遍历原型链并以这种方式构建它。仅仅查看对象的原型是不够的,因为 getter 可以从对象类的任何超类继承。
这是一个执行此操作的递归函数:
function getAllPropertyDescriptors(obj) {
if (!obj) {
return Object.create(null);
} else {
const proto = Object.getPrototypeOf(obj);
return {
...getAllPropertyDescriptors(proto),
...Object.getOwnPropertyDescriptors(obj)
};
}
}
Run Code Online (Sandbox Code Playgroud)
的输出JSON.stringify(getAllPropertyDescriptors(thing))如下。myGetter是第三个属性描述符;如果您不使用 JSON.stringify ,则实际输出还包括对实际函数的引用,因此您可以查看它们是否具有get/set属性。
{
"myProperty": {"value": 22, "writable": true, "enumerable": true, "configurable": true},
"constructor": {"writable": true, "enumerable": false, "configurable": true},
"myGetter": {"enumerable": false, "configurable": true},
"__defineGetter__": {"writable": true, "enumerable": false, "configurable": true},
"__defineSetter__": {"writable": true, "enumerable": false, "configurable": true},
" hasOwnProperty ": {"writable": true, "enumerable": false, "configurable": true},
"__lookupGetter__": {"writable": true, "enumerable": false, "configurable": true},
"__lookupSetter__": {"writable": true, "enumerable": false, "configurable": true},
"isPrototypeOf": {"writable": true, "enumerable": false, "configurable": true},
"propertyIsEnumerable": {"writable": true, "enumerable": false, "configurable": true},
"toString": {"writable": true, "enumerable": false, "configurable": true},
"valueOf": {"writable": true, "enumerable": false, "configurable": true},
"__proto__": {"enumerable": false, "configurable": true},
"toLocaleString": {"writable": true, "enumerable": false, "configurable": true}
}
Run Code Online (Sandbox Code Playgroud)
您可以将其转换为迭代版本,但这可能是不必要的,因为大多数原型链都很短,并且迭代版本需要一些争论才能以正确的顺序进行覆盖。
| 归档时间: |
|
| 查看次数: |
3734 次 |
| 最近记录: |