简体   繁体   English

with(window){}不适用于IE中的新弹出窗口

[英]with (window) {} doesn't work for new pop-up window in IE

I open a window, and want to perform some calculation on some condition. 我打开一个窗口,想在某些条件下进行一些计算。 Problem is in IE, only first call of test (from ready ) is performed from new window, but subsequent calls of test (set with setTimeout) are executed in parent window and not for new window (ie win ). 问题出在IE中,只有第一次test调用(从ready )是从新窗口执行的,但后续的test调用(使用setTimeout设置)在父窗口中执行而不是在新窗口中执行(即win )。

It works fine in FF. 它在FF中工作正常。

illustrating code (this code is in parent window): 说明代码(此代码在父窗口中):

var win = window.open(some_url, window_name, argument_string);

with (win) {
    function test() {
        alreadyrunflag += 1;
        if (alreadyrunflag < 10) {
            window.setTimeout(function() { test(); }, 500);
        }else { 
            //perform calculation
        }
    }

    jQuery(win.document).ready(function() {
        alreadyrunflag = 0
        test();          
    });
}

I would strongly recommend against using with in this situation (and, frankly, almost any other). 我会强烈建议不要使用with在这种情况下(,坦率地说,几乎任何其他)。 Instead, simply write win. 相反,只需写下win. everywhere necessary. 无处不在。 Like Eric Meyer, I'm not a huge fan of "considered harmful" essays, but this one by Douglas Crockford I'm in full agreement with. 就像Eric Meyer一样,我不是 “被认为有害”的散文的忠实粉丝 ,但道格拉斯·克罗克福德的这篇文章我完全赞同。

with modifies the "scope chain" in a way that it takes a seriously advanced knowledge of JavaScript to understand fully. with修改“作用域链”,因为它采用的JavaScript认真先进的知识充分理解的方式。 See Crockford's essay for details. 有关详细信息,请参阅Crockford的文章。 It also introduces speed penalties (though granted, while I've heard people rant about them, I doubt the costs are really that high). 它还引入了速度惩罚(虽然我已经听过人们对它们的咆哮,但我怀疑成本真的那么高)。 The effects on maintainability are just unacceptable. 对可维护性的影响是不可接受的。 Also, you can't use it in the new strict mode ( MDC link ), which is a useful mode that helps you avoid some common bugs. 此外,您不能在新的严格模式( MDC链接 )中使用它,这是一种有用的模式,可以帮助您避免一些常见的错误。

In this case, it seems to me that the scope chain should resolve in the way you're expecting (and the way Firefox apparently is doing it), but frankly I'm not shocked at all that IE's JScript implementation doesn't handle it the same way. 在这种情况下,在我看来,范围链应该以您期望的方式解决(以及Firefox显然正在这样做的方式),但坦率地说,我对IE的JScript实现无法处理它并不感到震惊以同样的方式。 And/or it may be an issue with which jQuery ends up getting used (the one in the opening window or the one in the just-opened window; you can't be sure, and it would be timing-dependent...yuck). 和/或它可能是jQuery最终被使用的问题(打开窗口中的那个或刚刚打开的窗口中的那个;你不能确定,它会依赖于时间... yuck )。

Putting a function declaration in a structure like if , for or with —anywhere other than directly inside a function body or global scope—is invalid in ECMAScript on a basic grammar level. function声明放在ifforwith -any之外的结构中, for不是直接在函数体或全局范围内 - 在基本语法级别的ECMAScript中无效。 Browsers typically let you get away with it, but what actually happens when you do varies from browser to browser, so you should never rely on it. 浏览器通常会让您逃脱它,但是当您执行操作时实际发生的事情因浏览器而异,因此您永远不应该依赖它。

This case demonstrates one of the problems: in Firefox, the function statement is interpreted as the non-standard Mozilla JavaScript extension FunctionStatement , which treats it as if you'd used a FunctionExpression , evaluated inline when you expected. 这一案例证明了的问题之一:在Firefox中, function声明被解释为非标准Mozilla的JavaScript扩展FunctionStatement ,这将其视为如果你使用的FunctionExpression ,在线评估,当你的预期。

But in IE, the function statement is interpreted in the same way as a kosher FunctionDeclaration and 'hoisted': evaluated at the start of the function that contains it. 但是在IE中, function语句的解释方式与kosher FunctionDeclaration和'hoisted'相同:在包含它的函数的开头计算。 It does not gain the with statement's value as an extra scope (and even if it did, win hasn't been assigned yet, so you'd be putting undefined on the scope chain!). 它没有将with语句的值作为额外的范围获得(即使它确实如此,还没有分配win ,所以你要在范围链上放置undefined的!)。

So you could get around it by using the FunctionExpression explicitly: 因此,您可以通过显式使用FunctionExpression来解决它:

with (win) {
    test= function() { ... };
}

But I'd seriously not recommend it. 但我真的不推荐它。 As TJ said, with absolutely sucks. 随着TJ说, with绝对吸。 It's abolished in ECMAScript Fifth Edition's Strict Mode. 它在ECMAScript第五版的严格模式中被废除了。 Don't use it. 不要使用它。 (And the timing issues mentioned in the comments. Yuck indeed.) (以及评论中提到的时间问题。确实。)

If you really want to inject test into the child window, say so directly: win.test= function() { ... }; 如果你真的想将test注入子窗口,请直接说: win.test= function() { ... }; . However, I don't see any need to do so here. 但是,我认为没有必要这样做。 You can perfectly well look at the child window from outside without having to put a copy of the function in a property of the child window. 您可以从外部完美地查看子窗口,而无需将该函数的副本放在子窗口的属性中。 Even if you do so, it won't change the scope of the code in the function. 即使您这样做,也不会改变函数中代码的范围。 And giving documents a copy of functions from other documents is dodgy as in IE, if a document is unloaded, all the functions defined in that document break. 向文档提供其他文档中的函数副本是狡猾的,如在IE中,如果文档被卸载,该文档中定义的所有函数都会中断。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM