When running the following block of code, FF and Chrome output
typeof(hiya) = string while IE7/8 output
typeof(hiya) = undefined.
Each of the following makes the problem go away:
var hiya = 1to
var hiya2 = 1.
var hiya = 1to
window.hiya = 1.
var hiya = 1to
hiya = 1.
What is happening? Is there a scoping bug in IE?
IE is dumb, it doesn't recognize that
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.
Last note to clarify what JS parsers do to your code. When the JS parser sees your code, it transforms it into the following:
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.
The core issue can be seen here http://jsfiddle.net/Raynos/UxrVQ/ I have yet to find out why IE overwrites window.hiya without checking.
From the specification. Page 38:
For each VariableDeclaration or VariableDeclarationNoIn in the code, create a property of the variable object whose name is the Identifier in the VariableDeclaration or VariableDeclarationNoIn, whose value is undefined and whose attributes are determined by the type of code. If there is already a property of the variable object with the name of a declared variable, the value of the property and its attributes are not changed.
A possible explanation could be that in global scope IE differentiates between the
window object and the
variable object for global scope when declaring variables. Alternatively setting a property on the
window object directly might not set the same property on the
variable object. If you can find a formal JScript specification or have the source of IE lying around then we can find out exactly what the quirk is.
Thanks to @TimDown & @JuanMendes pointing out that's an issue with whether writing a property to the window object is a variable declaration.
variable declaration gets moved to the top of the block. Even if the code is dead. In IE for some reason it will declare hiya as a local variable even though it classes with the property of the same name stored on window.
What's happening is that your declaring a variable called hiya. The var statement automatically gets removed to the top of the block. An if statement isn't a block, a function is. So event if the code never gets run in the block the variable still gets declared.
In firefox it'll recognise that window.hiya is a declaration of hiya.
In IE the declaration in the second script overwrites it
What it's actaully doing
// 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(...)
The solution is simply namespacing. You're using the same name in two places and accessing it in two different names. Either use different names or use closures to give local scope.
What you encountered is due to:
varbeing a statement
var statement before before anything else, but it will not evaluate the assignment expression, therefor
hiya will default to the value of
As Raynos already stated IE will execute each scripts on its own, therefore the behavior described above, will results in
hiya being undefined.
©2020 All rights reserved.