为什么 IE 核对 window.ABC 变量? [英] Why does IE nuke window.ABC variables?
问题描述
当运行以下代码块时,FF 和 Chrome 输出 typeof(hiya) = string
而 IE7/8 输出 typeof(hiya) = undefined
.
When running the following block of code, FF and Chrome output typeof(hiya) = string
while IE7/8 output typeof(hiya) = undefined
.
<html>
<body>
<script type="text/javascript">
window.hiya = 'hiya';
</script>
<script type="text/javascript">
if( false ) {
var hiya = 1;
}
document.write( "typeof(hiya) = "+ typeof(hiya) );
</script>
</body>
</html>
以下每一项都会使问题消失:
Each of the following makes the problem go away:
- 将所有内容组合成一个
块.
- 删除
if
块. - 将
var hiya = 1
重命名为var hiya2 = 1
. - 将
var hiya = 1
重命名为window.hiya = 1
. - 将
var hiya = 1
重命名为hiya = 1
.
- Combining everything into a single
<script>
block. - Removing the
if
block. - Renaming
var hiya = 1
tovar hiya2 = 1
. - Renaming
var hiya = 1
towindow.hiya = 1
. - Renaming
var hiya = 1
tohiya = 1
.
发生了什么? IE 中是否存在范围错误?
What is happening? Is there a scoping bug in IE?
推荐答案
IE 很笨,它不承认 window.varName
和 var varName
访问相同在某些情况下是可变的.
IE is dumb, it doesn't recognize that window.varName
and var varName
access the same variable in some cases.
当遇到新的 script 标签时,它首先初始化所有用 var 声明的变量.它不运行 var 语句(将其初始化为hiya"的部分).它只是将其初始化为未定义.如果之前用 var 声明它就不会这样做.
When a new script tag is encountered, it first initializes all the variables declared with var. It doesn't run the var statement (the part that would initialize it to "hiya"). It just initializes it to undefined. It won't do that if it was previously declared with var though.
如果您的代码位于单个脚本标记中,则不会发生此错误.另外,如果hiya的第一个声明是用var完成的,也不会发生这个错误.
If your code was in a single script tag, this error would not happen. Also, if the first declaration of hiya was done with var, this error also wouldn't happen.
具体来说,在你的第二个脚本标签中,IE 首先查找 var 语句,它找到一个 var var hiya = 1
;然后它说,hiya 之前没有用 var 语句初始化(IE 愚蠢,其他浏览器识别 window.hiya 做同样的事情)并初始化 hiya,在执行任何代码之前覆盖 window.hiya.
Specifically, in your second script tag, IE first looks for var statements, it finds a var var hiya = 1
; Then it says, hiya hasn't been initialized with a var statements previously (IE being dumb, other browsers recognize that window.hiya does the same thing) and initializes hiya, overwriting window.hiya before executing any code.
可能的解决方案:
- 将您的代码保存在同一个脚本标签中
- 不要用 window.hiYa 初始化变量
- 如果您不控制其中一个脚本,请确保首先使用使用 var 的脚本
最后一条说明 JS 解析器对您的代码做了什么.当 JS 解析器看到您的代码时,它会将其转换为以下内容:
Last note to clarify what JS parsers do to your code. When the JS parser sees your code, it transforms it into the following:
<html>
<body>
<script type="text/javascript">
window.hiya = 'hiya';
</script>
<script type="text/javascript">
// IE is dumb, it doesn't recognize that hiya is already
// defined as window.hiya, so it's initialized to undefined here
var hiya;
if( false ) {
hiya = 1;
}
document.write( "typeof(hiya) = "+ typeof(hiya) );
</script>
</body>
</html>
所以如果你把所有东西都放在一个脚本标签中,这就是代码(在 JS 引擎将 var 语句移到顶部之后),所以你可以看到 IE 不可能把它搞砸,因为您的 window.hiya
分配将在移至顶部的 var 之后.
So if you put everything into one script tag, this is what the code would be (after the JS engine moved the var statements to the top), so you can see that there is no way the IE could mess it up, since your window.hiya
assignment would be after the var that was moved to the top.
<html>
<body>
<script type="text/javascript">
var hiya;
window.hiya = 'hiya';
if( false ) {
hiya = 1;
}
document.write( "typeof(hiya) = "+ typeof(hiya) );
</script>
</body>
</html>
这篇关于为什么 IE 核对 window.ABC 变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!