在 document-start 和 document-end 都需要添加各自的对比代码。
document-start:
// === Step 1: 记录 baseline ===
if (!window.__baselineGlobals) {
window.__baselineGlobals = {};
Object.getOwnPropertyNames(window).forEach(name => {
try {
let desc = Object.getOwnPropertyDescriptor(window, name);
// 保存 descriptor 和 value(如果是函数/对象只保存引用,不做深拷贝)
window.__baselineGlobals[name] = {
desc,
value: window[name]
};
} catch (e) {
// 某些属性可能抛异常(如跨域对象),忽略
}
});
console.log("✅ 已保存 window 初始全局属性快照。刷新页面后再次运行此 Snippet 进行对比。");
}
document-end:
if (!window.__baselineGlobals) {
//【西西 2025-09-23 152258】不应该走到这一步
debugger;
window.__baselineGlobals = {};
Object.getOwnPropertyNames(window).forEach(name => {
try {
let desc = Object.getOwnPropertyDescriptor(window, name);
// 保存 descriptor 和 value(如果是函数/对象只保存引用,不做深拷贝)
window.__baselineGlobals[name] = {
desc,
value: window[name]
};
} catch (e) {
// 某些属性可能抛异常(如跨域对象),忽略
}
});
console.log("✅ 已保存 window 初始全局属性快照。刷新页面后再次运行此 Snippet 进行对比。");
} else {
//【西西 2025-09-23 152304】走到这一步是符合预期的
debugger;
// === Step 2: 对比 ===
let before = window.__baselineGlobals;
let afterNames = Object.getOwnPropertyNames(window);
let added = afterNames.filter(k => !before[k]);
let removed = Object.keys(before).filter(k => !afterNames.includes(k));
let modified = [];
Object.keys(before).forEach(name => {
if (afterNames.includes(name)) {
try {
let currentDesc = Object.getOwnPropertyDescriptor(window, name);
let baseline = before[name];
// 判断 descriptor 是否不同
let descChanged = JSON.stringify(currentDesc) !== JSON.stringify(baseline.desc);
// 判断 value 是否被替换(引用对比,不是深度内容对比)
let valueChanged = window[name] !== baseline.value;
if (descChanged || valueChanged) {
modified.push({
name,
descChanged,
valueChanged,
oldType: typeof baseline.value,
newType: typeof window[name]
});
}
} catch (e) {
// 有些 getter 会报错,忽略
}
}
});
console.group("🌍 Window 全局对象变更情况");
console.log("➕ 新增的全局变量:", added);
console.log("➖ 被移除的全局变量:", removed);
console.log("✏️ 被重写/修改的全局变量:", modified);
console.groupEnd();
// 清理快照,方便下次重新记录
delete window.__baselineGlobals;
}