Javascript 与(window){}donds';不适用于IE中的新弹出窗口

Javascript 与(window){}donds';不适用于IE中的新弹出窗口,javascript,Javascript,我打开一个窗口,想在某些条件下执行一些计算。 问题出在IE中,从新窗口仅执行第一次调用测试(从就绪), 但是test(设置为setTimeout)的后续调用在父窗口中执行,而不是在新窗口中执行(即win) 它在FF中运行良好 说明代码(此代码位于父窗口中): var-win=window.open(一些url、窗口名称、参数字符串); 有(赢){ 功能测试(){ alreadyrunflag+=1; 如果(alreadyrunflag

我打开一个窗口,想在某些条件下执行一些计算。 问题出在IE中,从新窗口仅执行第一次调用
测试
(从
就绪
), 但是
test
(设置为setTimeout)的后续调用在父窗口中执行,而不是在新窗口中执行(即
win

它在FF中运行良好

说明代码(此代码位于父窗口中):

var-win=window.open(一些url、窗口名称、参数字符串);
有(赢){
功能测试(){
alreadyrunflag+=1;
如果(alreadyrunflag<10){
setTimeout(函数(){test();},500);
}否则{
//计算
}
}
jQuery(win.document).ready(函数(){
alreadyrunflag=0
test();
});
}

我强烈建议在这种情况下(坦率地说,几乎任何其他情况下)不要将
一起使用。相反,只要在任何需要的地方编写
win.
。和埃里克·迈耶一样,我对“被认为有害”的文章也持怀疑态度,但我完全同意道格拉斯·克罗克福德(Douglas Crockford)的观点

with
修改“作用域链”的方式需要掌握JavaScript的高级知识才能完全理解。详见克罗克福德的文章。它还引入了速度惩罚(虽然是理所当然的,但我听到人们对它们大肆抱怨,我怀疑代价是否真的那么高)。对可维护性的影响是不可接受的。另外,您不能在新的strict模式()中使用它,这是一种帮助您避免一些常见错误的有用模式


在这种情况下,在我看来,作用域链应该以您期望的方式(以及Firefox显然正在这样做的方式)进行解析,但坦率地说,IE的JScript实现并没有以同样的方式处理它,我一点也不感到震惊。和/或它可能是一个问题,
jQuery
最终会被使用(打开窗口中的一个或刚刚打开的窗口中的一个;您不能确定,而且它会依赖于时间……糟糕)。

函数
声明放在类似
if
的结构中,
for
with
-在基本语法级别上,ECMAScript中除了直接位于函数体或全局作用域之外的任何位置都是无效的。浏览器通常可以让你逍遥法外,但实际发生的情况因浏览器而异,所以你永远不应该依赖它

本例演示了其中一个问题:在Firefox中,
function
语句被解释为非标准的Mozilla JavaScript扩展
FunctionStatement
,该扩展将其视为使用了一个
FunctionExpression
,在您预期的时间内联计算

但是在IE中,
function
语句的解释方式与犹太
FunctionDeclaration
和“highed”语句的解释方式相同:在包含它的函数的开头进行计算。它不会以
语句的值作为额外的作用域来获得
(即使它获得了,
win
还没有被分配,所以您将把
未定义的
放在作用域链上!)

因此,您可以通过显式使用
函数表达式来绕过它:

with (win) {
    test= function() { ... };
}
但我真的不推荐。正如TJ所说,
with
绝对糟糕透了。它在ECMAScript第五版的严格模式中被废除。不要用它。(还有评论中提到的时间问题。真恶心。)


如果确实要将
test
注入子窗口,请直接说:
win.test=function(){…}。然而,我认为没有必要这样做。您完全可以从外部查看子窗口,而不必将函数的副本放入子窗口的属性中。即使这样做,也不会改变函数中代码的范围。给文档一份来自其他文档的函数副本是不可靠的,就像IE中那样,如果一个文档被卸载,那么该文档中定义的所有函数都会中断。

的确如此。例如,查看
window.setTimeout
:这可能会解决
win.window.setTimeout
,或者只是
window.setTimeout
。为什么IE如此(粗鲁)!(这是我在IE中遇到javascript问题的经验。)@Shanta:IE确实存在严重问题,这是毫无疑问的。:-)IE8中有很多改进,这些迹象对IE9是有益的。最后但是,公平地说,让我们记住,IE也是我们拥有一些真正有用的功能的原因(此后被其他浏览器——以及W3C——采用的微软IE创新包括Ajax[
XMLHttpRequest
]和
innerHTML
,没有它们,当前的许多web将很难编写)。所以,好吧,如果微软没有的话,其他人可能会这么做,但他们还是这么做了——而且他们很早就这么做了…@Marcel:一个很好的观点。它将解析为
win.window.setTimeout
(在兼容的实现中),但我们大多数人都不会这么看它!同样的事情也适用于
jQuery
——是外部窗口中的jQuery,还是内部窗口中的
jQuery
?可能性取决于时间(新窗口是否已完成检索和解析jQuery脚本文件)。YuckI完全同意你关于这些创新的看法(毕竟,IE 6在它的时代是对许多其他浏览器的真正改进),但为什么它们不能以一致的方式实现自己的
innerHTML
?哦,Shanta的大括号并没有错配,正如我错误地认为的那样,虽然没有语句(只有注释)的行不会被解释为
else
语句(当然这只是一个示例,真正的代码显然包含语句(块))。+1也是一个很好的观点。起初我没有看到声明,只看到了表达式。
with
有它的用途,但是这个
with (win) {
    test= function() { ... };
}