为什么即核弹窗口。ABC变量?
-
25-09-2019 - |
题
时运行以下的方框代码,FF和铬输出 typeof(hiya) = string
同时,IE7/8输出 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>
以下每个使问题消失:
- 结合成一个单一的一切
<script>
块。 - 除去
if
块。 - 重命名
var hiya = 1
要var hiya2 = 1
. - 重命名
var hiya = 1
要window.hiya = 1
. - 重命名
var hiya = 1
要hiya = 1
.
发生了什么事? 有一个范围中的错误IE?
解决方案
即是愚蠢的,它不承认 window.varName
和 var varName
访问的同一变量,在某些情况下。
当一个新的脚本标记是所遇到的,这一初始化的所有声明的变量与var.它不能运行var的声明(第一部分,将其初始化到"你好").这只是初始化到不确定的。它不会这样做,如果它以前宣布的与var虽然。
如果你的代码是在一个脚本标记,这个错误不会发生。此外,如果第一宣言》的你好做var,这一误差也就不会发生。
具体而言,在你的第二个脚本的标签,即第一个看起来对var声明,它认为var var hiya = 1
;然后说,嘿没有被初始化var发言之前(即被愚蠢的,其他浏览器,认识到窗口。你好做同样的事情)和初始化嘿,复盖窗口。你好,然后再执行代码。
可能的解决方案:
- 保持你的代码在同一脚本标记
- 不初始化的变量的窗口。你好
- 如果你不控制的一个脚本,确保脚本,使用var来第一次
最后注意到澄清什么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>
所以如果你把一切都放入一个脚本的标签,这是什么代码会(后JS发动机移var发言顶),所以你可以看看有没有办法即可能搞砸了,因为你 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>
其他提示
核心问题可以在这里看到 http://jsfiddle.net/Raynos/UxrVQ/ 我还没找出为什么即将复盖窗口。你好没有检查。
[编辑]
从说明书。38页:
每个VariableDeclaration或 VariableDeclarationNoIn在代码, 创建一个酒店的可变 目,其名称的标识符 该VariableDeclaration或 VariableDeclarationNoIn,其价值 是不确定的,其属性 决定通过该类型的代码。如果 已经有一个酒店的 可变的目的名称 宣布变量,值 财产及其特性不是 改变。
一个可能的解释可能是,在全球范围,即区分的 window
目和 variable object
全球范围的时候,宣布的变量。或者设置一个酒店的 window
目直接可能不是设置同一财产上的 variable
对象。如果你能找到一个正式的JScript规范,或者有的来源,即躺在那么我们就可以找出究竟是什么怪癖是。
[/编辑]
由于@TimDown&@JuanMendes指出的一个问题是否编写一个酒店的窗口对象是一个可变的宣言》。
问题:
变宣言》得到移动到的区块。即使代码是死的。在即由于某些原因,它将宣布你好作为一个地方的变量即使这类财产的相同的姓名保存在窗口。
说明:
发生了什么,那是你的声明变量叫你好.Var的声明自动被删除的顶部区块。如果一个声明不是一块的功能。使事件如果代码从来没有得到运行中的方块的变量仍然得到宣布。
在火狐,它将认识到,窗口。你好是宣布你好.
在即《宣言》在第二个脚本将复盖它
什么某事做
在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(...)
在即:
// 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(...)
该方案是简单地命名空间.你在使用相同的名称在两个地方,并访问这两个不同的名称。无论是使用不同的名称或使用封锁给地方范围。
什么你遇到的是由于:
var
被一个声明- 有没有方块的范围JS
- 声明得到执行之前的运行代码
所以会发生什么情况是,JavaScript会执行的 var
发言之前,任何东西之前,但它没有评估的分配的表达,为此 hiya
将默认值 undefined
.
作为Raynos已经表示即将执行的每一个脚本上自己,因此该行为如上所述,结果在 hiya
正在不确定的。