Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/407.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Javascript中清除窗口对象中的自定义变量_Javascript_Internet Explorer 7_Global - Fatal编程技术网

在Javascript中清除窗口对象中的自定义变量

在Javascript中清除窗口对象中的自定义变量,javascript,internet-explorer-7,global,Javascript,Internet Explorer 7,Global,这是一个棘手的问题,已经让我挠头好几天了 我正在做一个项目,这个项目涉及到一个十年前的web应用程序,并将其作为一个单页应用程序进行修改。应用程序是巨大的-我们必须工作的时间,相当紧张,所以必须做一些捷径 然而,总的来说,我对我们取得的成就印象深刻,因为我们必须克服一些有趣的技术障碍 其中之一涉及清除所有自定义窗口变量。因为我们正在动态地重新加载应用程序的不同页面,所以我们需要清除所有自定义变量,以避免冲突。我们首先要做的是,加载应用程序的基本引导,并将窗口对象上的所有属性保存在一个数组中 然后

这是一个棘手的问题,已经让我挠头好几天了

我正在做一个项目,这个项目涉及到一个十年前的web应用程序,并将其作为一个单页应用程序进行修改。应用程序是巨大的-我们必须工作的时间,相当紧张,所以必须做一些捷径

然而,总的来说,我对我们取得的成就印象深刻,因为我们必须克服一些有趣的技术障碍

其中之一涉及清除所有自定义窗口变量。因为我们正在动态地重新加载应用程序的不同页面,所以我们需要清除所有自定义变量,以避免冲突。我们首先要做的是,加载应用程序的基本引导,并将窗口对象上的所有属性保存在一个数组中

然后,在加载每个新页面之前,我们循环遍历窗口属性并清除不在已保存数组中的所有对象(将窗口状态恢复到加载页面之前的状态)

现在,除了IE7和IE8(两者都需要支持)之外,这在我们测试过的所有浏览器中都可以正常工作。问题似乎是全局变量似乎并不总是在窗口对象上注册

有人对这个问题有什么见解吗?你知道如何应对IE7吗

任何信息将不胜感激

编辑: 在引导加载时,我们执行以下操作:

for (i in window) {
   this.globalVars[i] = 1;
}
然后,当我们加载一个新页面(通过AJAX)时,我们会:

最终解决方案:

最后,在有限的时间内,最简单的修复方法是简单地更改定义为var x的所有变量;到var x=null

然而,我找到了另一个解决办法。这里有一个小的库,我将其用作替代解决方案的起点:

它并不完美(可能需要一些调整使其更加稳定,例如在AJAX调用周围添加一个try-catch块,以便跨域脚本不会使其崩溃)。它的工作方式是解析所有外部脚本文件和内部脚本,提取大量单词,然后用于清除窗口对象中的属性

我们实际上经历了一些非常奇怪的事情-这个脚本没有正确地提取我们的很多变量。。。事实证明,它使用document.scripts获取页面上所有加载的脚本,以便能够循环遍历它们并解析它们。问题是jQuery不会以这种方式加载页面上的外部页面。它所做的只是根据我所知将代码传递给exec。因此,实际上没有向页面添加脚本标记

解决方法是解析原始AJAX响应并存储对所有脚本标记的引用(以及,我想,提取内联脚本),然后修改库以处理这些文件。这应该是可行的,但由于速度的原因,所有这些处理过程都太可怕了——发现我们可以简单地对所有变量定义进行搜索和替换,并且在不需要为每个页面加载大量工作的情况下完成大部分工作,这让我们清楚地知道我们应该走哪条路。

查看此问题:

在IE中,除非将全局变量显式定义为窗口对象的属性,否则它是不可枚举的

因此,如果您正在分配这样的变量:

var number = 42; // not inside any function
window.number = 42; 
this.number = 42; 
当您在
窗口中迭代时,它不会显示。您必须这样定义所有全局变量:

var number = 42; // not inside any function
window.number = 42; 
this.number = 42; 
或者像这样:

var number = 42; // not inside any function
window.number = 42; 
this.number = 42; 

是否已检查循环期间未显示的属性是否配置为不可枚举。因为如果对象的属性不可枚举,那么它就不会在循环期间“显示”。您可以使用下面的方法“propertyIsEnumerable”检查这一点

例如:

var o = {x:1, y:2, z:3}; // Three enumerable own properties
o.propertyIsEnumerable("toString") // => false: not enumerable
作为旁注:

根据ECMAScript 5,for/in循环每次运行一次循环体 指定对象的可枚举属性(自有或继承),指定 循环变量的属性。对象继承的内置方法不是 可枚举,但代码添加到对象的属性是可枚举的(除非
就我所知,如果您希望这是一个“快速”的解决方案,确保100%的全局变量被重置,并且这与旧版本兼容,那么您基本上必须保存您修改的窗口/文档属性的初始值。。。并手动为特定页面上的每个全局变量写入空值

如果你想它是100%准确,完全BC与旧的IE。。。而且没有任何形式的重构。。。这就是我对你未来的期望

你的公司听起来像是我认识的一些公司(我相信每个人都知道一些)--
“如果我们告诉开发人员让奇迹发生,那么奇迹可以在没有钱的情况下在短时间内发生。”

如果归结到这一点,我会选择并手动修复全局变量问题(或者编写解析器在页面上查找全局范围的变量,或者至少指向它们可能所在的位置)。 框架的其余部分可以被拼凑在一起。。。不过,如果可能的话,我最终还是希望对页面进行沙箱处理(首先,如果没有全局文件,这将使整个州的事情变得毫无意义)

但是是的。。。手动为每个页面的全局设置空值,或手动修复它们,以将其作为
窗口[key]
(如果绝对必要)应用,或作为
以前的\u全局属性[key]
应用,或在完全不同的范围内应用,包含在函数中。 所有这些都将是向后兼容的,所有这些都将是不可估量的可怕


但是,像这样的解决方案和将全局性的问题转化为可以在以后使用/维护的可行方案,工作量大致相同,是吗?

如果您将旧脚本包装在一个闭包中,并保存/导出需要持久化的变量,该怎么办?

我建议使用delete,一个鲜为人知的js功能来正确地去除全局变量,例如

delete window.varname;
<