使用for-in遍历window对象:代码无法返回带自定义属性的对象名数组求助
为啥用
for-in遍历window拿不到自定义属性? 嘿,我太懂这种踩坑的感觉了!用for-in遍历window想捞出自定义属性数组却失败,大概率是踩了window属性枚举性和原生属性的坑——我给你拆解清楚,再给几个靠谱的解决方案。
核心问题出在哪?
window的原生属性特性与for-in的遍历规则不匹配:全局作用域用var声明的变量、函数声明,会被挂载为window的不可枚举属性,for-in默认只遍历可枚举属性,自然拿不到它们;而直接赋值window.myProp = 'xxx'的属性是可枚举的,但for-in还会遍历原型链上的属性,容易混入原生无关内容。for-in会遍历原型链:哪怕你加了hasOwnProperty(),还是会碰到一些原生可枚举属性,很难精准筛选出自定义的内容。
靠谱的解决方案
方案1:提前记录原生属性,用Object.keys()过滤
这是最常用的方法——先在页面加载最开始(还没添加自定义属性时)记录window的所有可枚举自有属性,之后对比筛选:
// 页面初始化时立即执行,记录原始window属性 const originalWindowKeys = new Set(Object.keys(window)); // 假设之后你添加了自定义属性 window.myAppProp = '我是自定义属性'; window.userSettings = { theme: 'dark' }; // 筛选出自定义属性数组 const customWindowProps = Object.keys(window).filter(key => !originalWindowKeys.has(key)); console.log(customWindowProps); // ['myAppProp', 'userSettings']
方案2:获取所有自有属性(包括不可枚举的)
如果你的自定义属性是用var或函数声明添加的(这些是不可枚举的),用Object.getOwnPropertyNames()能拿到所有自有属性,覆盖更全面:
const originalWindowProps = new Set(Object.getOwnPropertyNames(window)); // 添加不可枚举的自定义属性(全局函数/var变量) var globalVar = '我是不可枚举的'; function globalFunc() {} // 添加可枚举的自定义属性 window.enumProp = '我是可枚举的'; const customProps = Object.getOwnPropertyNames(window) .filter(key => !originalWindowProps.has(key)); console.log(customProps); // ['globalVar', 'globalFunc', 'enumProp']
如果非要用for-in怎么办?
不推荐,但如果必须用,一定要加hasOwnProperty()检查,再结合原始属性过滤:
const originalWindowKeys = new Set(Object.keys(window)); const customProps = []; for (const key in window) { // 只遍历window自己的属性,且不是原生属性 if (window.hasOwnProperty(key) && !originalWindowKeys.has(key)) { customProps.push(key); } } console.log(customProps);
不过这个方法不如前两种稳定,因为for-in的枚举顺序不固定,还可能混入一些浏览器自带的可枚举属性。
额外提醒
- 如果是在ES模块环境中,全局变量不会挂载到
window上,这些方法都不适用——模块里的变量是模块作用域的,不会成为window的属性。 - 有些浏览器扩展会给
window加属性,这些也会被算作“自定义属性”,如果要排除它们,一定要在页面加载的最最开始就记录原始window属性,避免扩展干扰。
内容的提问来源于stack exchange,提问作者John Brown
相关产品推荐
相关产品推荐

