这是一篇关于使用JScript RuntimeObject(MSDN)调试的文章。虽然这些例子中的大多数在其他浏览器中不能运行,但在IE 5.5+中都能运行。
泄露的全局标识符
比如说你一不小心创建了一个全局属性,如:
function playRugby(players) { var items, i; len = items.length; // Global. } function kick() { var x = 10 y = 11; // As I makes y global. }
当调用playRugby时,创建了全局属性len,如果它尚未存在,那么就将items.length的值赋给它。同样,当调用kick时,创建了全局属性y。
这些全局变量都不是故意的。它们破坏了封装并泄露了执行的细节。这可能会导致冲突和棘手的依赖问题。
要检测这些不经意间创建的全局标识符,我们可以使用for in循环全局对象。Firebug的”DOM”标签提供了这个实用的全局检测。
遗憾的是,在IE中,for in不能枚举任何全局变量和函数声明。看看下面的例子:
// Property of global variable object. var EX1_GLOBAL_VARIABLE = 10; // Property of global object. this.EX1_GLOBAL_PROPERTY = 11; // Property of global variable object. function EX1_GLOBAL_FUNCTION(){} (function(){ var results = []; for(var p in this) { results.push(p); } alert("Leaked:\n" + results.join("\n")); })();
在IE中,结果包含一个window属性组合和用户定义的四个属性之一:EX1_GLOBAL_PROPERTY 。
那么,其它三个用户定义的属性发生了什么?为什么它们不能在for in循环中显示出来。
事实证明,枚举全局对象时将枚举已赋值的全局对象属性,而不枚举全局变量。
为什么全局属性能枚举而全局变量不能。经验告诉我们,JScript 给全局变量(用var声明)打上了DontEnum标记。由于全局对象是作为全局变量对象来定义的,这看起来似乎是一个合理的解释。这并不标准,但能解释IE中的行为。不过,Eric Lippert 提出了另一种解释:全局对象和全局变量对象是IE中两个不同的对象。
根据MS-ES3:
JScript 5.x 中的变量声明创建了全局对象的属性,该属性拥有DontEnum 特性。
出处:Denis'Blog
责任编辑:bluehearts
上一页 下一页 用JScript RuntimeObject检测全局污染 [2]
◎进入论坛网页制作、WEB标准化版块参加讨论,我还想发表评论。
|