在全局上下文中访问API类名



我正在写一些ES/JS工具。在DevTools中,我可以看到很多类,例如ArrayBuffer。然而,当我试图从window全局上下文中提取这些名称时,我看不到它们。这段代码在Chrome、FireFox和Opera中给出了类似的结果。

console.log('typeof window.ArrayBuffer:', 
typeof window.ArrayBuffer);
console.log("window.hasOwnProperty('ArrayBuffer'):", 
window.hasOwnProperty('ArrayBuffer'));
let c = 0;
for (let n in window) {
// console.log(n);
if (n == 'ArrayBuffer') {
console.log('FOUND: ArrayBuffer');
}
c++;
}
console.log(c + ' attributes checked')

如果我取消注释// console.log(n);行,我可以看到属性的名称,但没有类。

我如何访问这些类(API)名称?

这是对象的可枚举属性的问题。

for in(以及Object.keys/values/entries)是否非枚举属性的帐户:

window.hasOwnProperty('ArrayBuffer');       // true
window.propertyIsEnumerable('ArrayBuffer'); // false
// Therefore will not show up in for-in loop

要创建一个不可枚举的对象属性,一个例子是使用object . defineproperty

const obj = {a: 1, b: 2, c: 3};
for (const prop in obj) console.log(obj[prop]); // 1 2 3
Object.defineProperty(obj, "d", {
value: 4,
// enumerable: false,      // defaults to false!!
// set to true to make it enumerable
});
for (const prop in obj) console.log(obj[prop]); //  1 2 3 (no 4 visible)
// Same goes for iterating using Object.keys and Object.values:
console.log(...Object.values(obj)) // 1 2 3 (no 4 visible)

要获取一个对象的所有属性,你可以使用Object. getownpropertynames:

const props = Object.getOwnPropertyNames(window);
console.log(props.includes('ArrayBuffer'));                    // true
console.log(props.some(pr => pr === 'ArrayBuffer'));           // true
console.log(props.findIndex(pr => pr === 'ArrayBuffer') > -1); // true
console.log(props.length);                   // 963
console.log(Reflect.ownKeys(window).length); // 963
// See them all:
console.log(props);
// Loop them all:
// props.forEach(pr => console.log(pr));

请记住……仅在循环中可枚举属性-符号除外。

使用Reflect.ownKeys

获取带有符号的对象自身属性键的数组

反映。ownKeys方法返回目标对象自身属性键的数组。其返回值等于Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target))

额外的阅读:

  • 属性的可枚举性和所有权
  • 不可枚举对象属性的好处是什么

使用Object.getOwnPropertyNames()获取所有属性(包括非枚举属性,使用Symbol的属性除外)。然后循环查找类名:

Object.getOwnPropertyNames(window).forEach((n) => {
if (n === 'ArrayBuffer') {
console.log('FOUND: ArrayBuffer');
}
})

最新更新