Why does IE nuke window.ABC variables?

前端 未结 3 1681
心在旅途
心在旅途 2020-12-01 08:03

When running the following block of code, FF and Chrome output typeof(hiya) = string while IE7/8 output typeof(hiya) = undefined.

&         


        
3条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-12-01 08:27

    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.

    [Edit]

    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.

    [/Edit]

    Thanks to @TimDown & @JuanMendes pointing out that's an issue with whether writing a property to the window object is a variable declaration.

    The Issue:

    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.

    Explanation:

    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

    In 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(...)
    

    In 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(...)
    

    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.

提交回复
热议问题