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:
<script>
block.if
block.var hiya = 1
to var hiya2 = 1
.var hiya = 1
to window.hiya = 1
.var hiya = 1
to hiya = 1
.What is happening? Is there a scoping bug in IE?
IE is dumb, it doesn't recognize that window.varName
and var varName
access the same variable in some cases.
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.
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.
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.
Possible solutions:
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>
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>