副问题[/!--empirenews.page--]
这是一篇关于行使JScriptRuntimeObject(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")); })();// 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 特征。
列举方案:JScript RuntimeObject
行使JScript RuntimeObject要领列举全局属性与列举全局工具差异,你将行使一个正常的执行,列举由全局RuntimeObject要领返回的一个工具。
var GLOBAL_VAR1, GLOBAL_VAR2, GLOBAL_VAR3 = 1; GLOBAL_PROP1 = 12; function GLOBAL_FUNCTION(){} if(this.RuntimeObject){ void function() { var ro = RuntimeObject(), results = [], prop; for(prop in ro) { results.push(prop); } alert("leaked:n" + results.join("n")); }(); }var GLOBAL_VAR1, GLOBAL_VAR2, GLOBAL_VAR3 = 1; GLOBAL_PROP1 = 12; function GLOBAL_FUNCTION(){} if(this.RuntimeObject){ void function() { var ro = RuntimeObject(), results = [], prop; for(prop in ro) { results.push(prop); } alert(“leaked:n” + results.join(“n”)); }(); }
IE中的功效
在IE8和其余较低版本中,功效包罗GLOBAL_FUNCTION,GLOBAL_VAR3,GLOBAL_PROP1 (除此之外,还包罗window)。留意GLOBAL_VAR1 和GLOBAL_VAR2 并不包括个中。看来RuntimeObject并不网络未被赋值的任何变量,按照微软的文档,这不是指定的举动(以下有更多这方面的信息)。
微软的RuntimeObject文档
RuntimeObject是JScript 内置的扩展,JScript界说了七个附加的内置全局要领:ScriptEngine,ScriptEngineBuildVersion,ScriptEngineMajorVersion,ScriptEngineMinorVersion,CollectGarbage,RuntimeObject和GetObject。这些工具都是当地JScript工具,不要与宿主工具夹杂。
对付RuntimeObject,微软的JScript扩展MS-ES3EX声明如下:
RuntimeObject用来探求一个全局变量的属性,这些带著名称的属性匹配特定的模式。这个函数只探求全局工具中通过VariableStatement 或 FunctionDeclaration方法显式建设的属性,或是位于运算符左侧作为标识符隐式建设的属性。不能探求通过会见全局工具显式建设的属性。
大致的测试功效表白微软的文档是不靠谱的。
返回的工具不包罗添加到变量工具之上的全部标识符,只是那些被赋值的标识符。无论它们是通过VariableDeclaration,FunctionDeclaration来建设,照旧作为全局属性声明来建设都无关紧急。
查找通过FunctionBindingList建设的标识符示例
在JScriptFunction的FunctionBindingList 中,全部标识符将成为包括的变量工具的属性,如:
var foo = {}, undef, ro; (function(){ function foo.bar, baz(){} })(); ro = RuntimeObject(); alert([ro.foo.bar, "undef" in ro].join("n"));var foo = {}, undef, ro; (function(){ function foo.bar, baz(){} })(); ro = RuntimeObject(); alert([ro.foo.bar, "undef" in ro].join(“n”));
IE elerts
function foo.bar(){} false在除了IE的赏识器中运行JScript,在理会JScriptFunction 的FunctionBindingList时会准期地抛出SyntaxError(语法错误)。这是料想之中的,由于它是一个语法扩展。
书签
(编辑:湖南网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|