我刚刚了解到在DevTools控制台中调用keys(window)
(或Object.keys(window)
)会显示全局范围内的变量(source)。我在StackOverflow页面上调用了该代码并得到了这个结果:
变量i
引起了我的注意,因为它似乎在一个错误的全局范围内。我尝试找到负责声明i
的代码,但结果很麻烦(有很多代码和很多i
)。
获取说出
的控制台警告创建全局变量“i”(main.js:342)
可能很有用。我该如何实现该功能?
我认为每当创建新变量时我都需要某种事件。
__noSuchMethod__
(MDN)会很完美但它只涵盖方法(并且没有__noSuchProperty__
方法)。Object.observe
(HTML5 Rocks)没有透露有关创建属性的代码的任何信息(console.trace()
只给出了观察者函数的名称。)Object.prototype.watch
(MDN) - 与设置者相同,您必须指定一个属性名称。Object.preventExtensions(window)
(MDN)会导致错误堆栈跟踪。此解决方案的问题在于它会干扰脚本执行并可能会更改其行为。它也不允许我捕获错误并正确格式化。i
变量那么多,您可以使用setter找到声明。我的问题涉及这个问题的一般解决方案。答案 0 :(得分:4)
IMO你有两个不错的选择:
当你泄漏全球时,两个人都会对你大喊大叫。严格的模式可能会更好地用于您的用例。
答案 1 :(得分:1)
你确实完成了你的作业,你想到了我想到的所有事情,正如你所发现的那样,它们都不合适。
我能想到的唯一方法就是监视全局对象(这个例子使用window
作为全局对象:相应地修改Node或其他JavaScript容器)。这是一个监视新全局变量和删除全局变量的示例(如果您不需要监视删除,则可以删除该功能):
var globals = Object.keys(window);
var monitorGlobalInterval = 50;
setInterval(function(){
var globalsNow = Object.keys(window);
var newGlobals = globalsNow.filter(function(key){
return globals.indexOf(key)===-1;
});
var deletedGlobals = globals.filter(function(key){
return globalsNow.indexOf(key)===-1;
});
newGlobals.forEach(function(key){
console.log('new global: ' + key);
});
deletedGlobals.forEach(function(key){
console.log('global deleted: ' + key);
});
globals = globalsNow;
}, monitorGlobalInterval);
在此处查看此行动:http://jsfiddle.net/dRjP9/2/
答案 2 :(得分:0)
您可以尝试使用此方法获取已创建的全局变量列表:
(function(){
var differences = {},
ignoreList = (prompt('Ignore filter (comma sep)?', 'jQuery, Backbone, _, $').split(/,\s?/) || []),
iframe = document.createElement('iframe'),
count = 0; ignoreList.push('prop');
for (prop in window) {
differences[prop] = {
type: typeof window[prop],
val: window[prop]
}; count++;
}
iframe.src = 'about:blank';
iframe.style.display = 'none';
document.body.appendChild(iframe);
iframe = iframe.contentWindow || iframe.contentDocument;
for (prop in differences) {
if (prop in iframe || ignoreList.indexOf(prop) >= 0) {
delete differences[prop];
count--;
}
}
console.info('Total globals: %d', count);
return differences;
})();