eto*_*leb 25 javascript internet-explorer scope browser-bugs
运行以下代码块时,typeof(hiya) = string在IE7/8输出时输出FF和Chrome 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>
Run Code Online (Sandbox Code Playgroud)
以下每个问题都会消失:
<script>块中.if块.var hiya = 1为var hiya2 = 1.var hiya = 1为window.hiya = 1.var hiya = 1为hiya = 1.怎么了?IE中是否存在范围错误?
Jua*_*des 26
IE是愚蠢的,它在某些情况下无法识别window.varName并var varName访问相同的变量.
遇到新的脚本标记时,它首先初始化用var声明的所有变量.它不运行var语句(将其初始化为"hiya"的部分).它只是初始化为undefined.如果先前使用var声明它,它将不会这样做.
如果您的代码位于单个脚本标记中,则不会发生此错误.另外,如果hiya的第一个声明是用var完成的,那么这个错误也不会发生.
具体来说,在你的第二个脚本标记中,IE首先查找var语句,它会找到一个var var hiya = 1; 然后它说,hiya之前没有用var语句初始化(IE是愚蠢的,其他浏览器认识到window.hiya做同样的事情)并初始化hiya,在执行任何代码之前覆盖window.hiya.
可能的解决方案:
最后请注意,以澄清JS解析器对您的代码执行的操作.当JS解析器看到您的代码时,它会将其转换为以下代码:
<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>
Run Code Online (Sandbox Code Playgroud)
因此,如果你把所有东西都放在一个脚本标签中,这就是代码将会是什么(在JS引擎将var语句移到顶部之后),所以你可以看到IE没有办法弄乱它,因为你的window.hiya任务将在移动到顶部的var之后.
<html>
<body>
<script type="text/javascript">
var hiya;
window.hiya = 'hiya';
if( false ) {
hiya = 1;
}
document.write( "typeof(hiya) = "+ typeof(hiya) );
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
Ray*_*nos 10
核心问题可以在这里看到http://jsfiddle.net/Raynos/UxrVQ/我还没有找出为什么IE覆盖window.hiya而不检查.
[编辑]
从规范.第38页:
对于代码中的每个VariableDeclaration或VariableDeclarationNoIn,创建变量对象的属性,其名称为VariableDeclaration或VariableDeclarationNoIn中的标识符,其值未定义且其属性由代码类型确定.如果已存在具有声明变量名称的变量对象的属性,则不会更改该属性的值及其属性.
可能的解释是,在全局范围内,IE 在声明变量时区分window对象和variable object全局范围.或者,window直接在对象上设置属性可能不会在对象上设置相同的属性variable.如果你能找到一个正式的JScript规范或者有IE的来源,那么我们就可以找到确切的怪癖.
[/编辑]
感谢@TimDown和@JuanMendes指出,将属性写入窗口对象是一个变量声明是一个问题.
问题:
变量声明被移动到块的顶部.即使代码已经死了.在IE中出于某种原因,它会将hiya声明为局部变量,即使它使用存储在窗口中的同名属性进行分类.
说明:
发生的事情是你声明一个名为hiya的变量.var语句自动被移除到块的顶部.if语句不是块,函数是.因此,如果代码永远不会在块中运行,则变量仍然被声明.
在Firefox中,它会认识到window.hiya是hiya的声明.
在IE中,第二个脚本中的声明会覆盖它
什么是它的行为
在Firefox中:
// script block 1
var hiya; // window.hiya counts as a declaration
window.hiya = "hiya"; // set
// script block 2
if (false) hiya = 1;
document.write(...)
Run Code Online (Sandbox Code Playgroud)
在IE中:
// script block 1
window.hiya = "hiya";
// script block 2
var hiya; // redeclared here because window.hiya "isn't" a declaration
if (false) hiya = 1;
document.write(...)
Run Code Online (Sandbox Code Playgroud)
解决方案只是命名空间.您在两个地方使用相同的名称,并以两个不同的名称访问它.使用不同的名称或使用闭包来提供本地范围.
| 归档时间: |
|
| 查看次数: |
6655 次 |
| 最近记录: |