Declared Javascript Functions – Odd Parsing Behavior in IE

A function declared in a conditional block that evaluates to false gets defined in IE, but not in Firefox. That is a problem if you are trying to use an ‘ifdef’ or ‘require_once’ mechanism for defining functions. However, if the function is defined via assignment, the reference is not created, which is what you’d expect.


The reason that the unexpected definition is a problem is that declaring a function more than once can have some nasty side effects. Depending on when it happens, your objects can lose type information. Symptoms include methods in the parent class no longer being visible, and unexpected results from ‘instanceof’.

A large project that I’m finishing up is reorganizing the web client to load code dynamically as needed, from packages. Each package consists of a number of files, and each file defines one or more Javascript classes (functions). We need to be careful not to define a class more than once, so our build process surrounds each class definition with an ‘if’ block, using the standard idiom:

if (!defined("Foo")) {
function Foo() {
this.bar = 1;
}
define("Foo");
}

In Firefox, that works as expected. Foo will get defined only once. However, in IE, it will get defined each time the code above is parsed, leading to the side effects described above.

Our current workaround is to define the function via assignment:

if (!defined("Foo")) {
Foo = function() {
this.bar = 1;
}
define("Foo");
}

It seems that the IE parser must be doing a pass where it looks for function declarations and adds them to the symbol table regardless of the containing block. I’m assuming that’s not correct behavior, but I haven’t read the ECMAScript spec thoroughly.

Feel free to try this test page if you want to see it in action.

One Response to Declared Javascript Functions – Odd Parsing Behavior in IE

  1. Ben June 23, 2010 at 5:18 PM #

    Thanks so much. This is just what I was looking for. Well done.

Copyright © 2022 Zimbra, Inc. All rights reserved.

All information contained in this blog is intended for informational purposes only. Synacor, Inc. is not responsible or liable in any manner for the use or misuse of any technical content provided herein. No specific or implied warranty is provided in association with the information or application of the information provided herein, including, but not limited to, use, misuse or distribution of such information by any user. The user assumes any and all risk pertaining to the use or distribution in any form of any subject matter contained in this blog.

Legal Information | Privacy Policy | Do Not Sell My Personal Information | CCPA Disclosures