首先,我得想,怎么遍历window对象的所有属性。因为window是一个全局对象,所有全局变量都是它的属性。不过直接用for...in循环可能会遍历到很多内置属性和方法,比如document、console这些,可能需要过滤掉一些不可枚举的或者来自原型的属性。不过用户可能希望检查所有属性,不管是不是可枚举的,所以应该使用Object.getOwnPropertyNames来获取所有自身属性,包括不可枚举的。
但用户还提到不只是直接变量,还要遍历变量下的子元素。比如,如果window有一个属性a,而a对象又有属性b,那么也要检查a.b是否包含creation_id。这看起来像是一个递归遍历的问题。所以需要递归地检查每个对象的属性。
不过递归遍历可能会有问题,比如循环引用,比如对象之间相互引用导致无限循环。所以需要记录已经访问过的对象,避免重复遍历。可以用一个Set或者WeakSet来保存已经处理过的对象引用。
接下来,变量名包含“creation_id”的条件,指的是属性名中包含这个字符串,而不是属性值。所以需要检查每个属性的名称是否包含该字符串,而不是属性的值。例如,如果有一个属性名为“my_creation_id”,那么符合条件,需要输出这个变量名。
但是如何跟踪变量名的路径呢?比如,如果有一个对象window.a.b.c,其中c的属性名是“creation_id”,那么应该输出完整的路径,比如“a.b.c”吗?或者只需要输出属性名本身?用户的需求是输出变量名,可能是指完整的路径,但原问题描述没有明确说明。需要再仔细看问题。
function findAllCreationIdVariables() {
const visited = new WeakSet(); // 用于跟踪已访问对象,避免循环引用
function traverse(obj, path = '') {
if (obj === null || typeof obj !== 'object' && typeof obj !== 'function') {
return;
}
if (visited.has(obj)) return;
visited.add(obj); // 标记当前对象为已访问
try {
// 获取对象的所有自身属性(包括不可枚举属性)
const props = Object.getOwnPropertyNames(obj);
for (const prop of props) {
// 构建当前属性的完整路径
const currentPath = path ? `${path}.${prop}` : prop;
// 检查属性名是否包含目标字符串
if (prop.includes('creation_id')) {
console.log('发现变量:', currentPath);
}
try {
// 获取属性值(可能抛出异常)
const value = obj[prop];
// 递归遍历子属性(如果是对象/函数)
traverse(value, currentPath);
} catch (error) {
// 忽略无法访问的属性(如安全限制)
}
}
} catch (error) {
// 忽略无法获取属性列表的对象(如跨域iframe)
}
}
traverse(window); // 从window对象开始遍历
}
// 执行函数
findAllCreationIdVariables();