Liangliang Zheng
Liangliang Zheng

Reputation: 1785

Very weird thing in IE8.. Defined variable is recognized as 'undefined'

A very weird problem occurred, when I was trying to enable a lib (Beard.js) to support the javascript template engine Haml.

Haml could not be loaded correctly. I tracked down the code and find out that Haml has never been loaded into the page. After a lot of try and fail, I happened to make it work. The weird thing I found is:

in origin Haml lib, it is:

var Haml;

(function(){
    ...

    Haml = function(){ ... }

    ...
}());

I changed the code to :

var Haml;

(function(){
    ...

    window.Haml = function(){ ... }

    ...
}());

then it works..

WHY??? Shouldn't Haml be automatically recognized as defined in the global scope?

Environment - IE8
Haml.js - https://github.com/creationix/haml-js
Bear.js - https://github.com/jspopisno1/Beard

-------------- UPDATE ---------------

in Haml.js, it is:

var Haml;

(function(){
    ...

    Haml = function Haml(){ ... }

    ...
}());

I guess in the javascript, the statement "function Haml(){}" makes Haml a local var. However, why can Haml be loaded correctly in Firefox & Chrome????

Upvotes: 1

Views: 3446

Answers (3)

RobG
RobG

Reputation: 147343

> var Haml;
> (function(){
>     ...
>     Haml = function Haml(){ ... }
>     ... 
> }());

That code does not throw any errors in IE 8 for me. The part you are missing in your question is a following statement:

alert(typeof Haml);

which shows undefined in IE and function in Firefox and others.

The assignment to Haml is a named function expression (the name is optional) and yes, IE will create a variable in the current scope with the name, other browsers don't.

Upvotes: 3

davin
davin

Reputation: 45525

The problem is related to JScript (in versions up until IE8) having a bug whereby named function expressions leak into the enclosing scope. So named function expressions are parsed as function declarations (as well as function expressions), thereby automatically hoisting a local Haml variable into the local scope. After that, you set Haml = function(){} but that doesn't result in the global Haml because JScript finds a local variable with that identifier because it incorrectly leaked into the local scope. So while the local Haml is set correctly, the global one is never reached.

You can read about this more here.

Upvotes: 5

alex
alex

Reputation: 490143

Shouldn't Haml be automatically recognized as defined in the global scope?

Only if that code itself is in the global scope. If it is part of a function, the var will scope it to that function only.

Upvotes: 0

Related Questions