Kilometer0

Internet Explorer (IE) Cross-Window Javascript Object typeof Bug

Background:

On a recent project I was working with lots of Javascript objects that got passed into Flash. We had a popup window that we would also send objects to, then send them to flash. When testing Internet Explorer (IE6 and IE7) at the time, we noticed a weird bug. Whenever we tried to pass our Javascript object into Flash, it would fail with a weird error. Tracing out the object resulted in the correct object being used, but the same object passed to Flash in the original window worked and the one in the popup failed. The object had the same properties, the same functions, etc. I dug around into the SWFAddress code and saw that it was in an infinite loop, which errored out after awhile with a stack error… because of the recursive calls, while trying to serialize the object. The function went something like this:

  1. function serialize(obj)
  2. {
  3.  var newObj = {};
  4.    
  5.     for(var i in obj)
  6.     {
  7.      if(typeof obj[i] == "function") continue;
  8.        
  9.         if(typeof obj[i] == "object")
  10.         {
  11.          newObj[i] = serialize(obj[i]);
  12.         }
  13.         else
  14.         {
  15.          newObj[i] = obj[i];
  16.         }
  17.     }
  18.    
  19.     return newObj;
  20. }

That code may not be exactly right (its been a few months, so I’m writing it from memory), but you get the gist. It is recursively looking for all properties of an object that aren’t functions and sticks them into another object, which is then passed to flash.

Update:

There also seems to be a bug with all browsers when sending objects from one window to another, then checking “instanceof Function”.

Update #2:

The “instanceof Function” issue is not a bug but, what is in my opinion, a flaw in the ECMA spec. If you pass a function from one window another, then do … “myFunct instanceof window.opener.Function” then it will return true, but just “myFunc instanceof Function” will return false, because “Function” is not in the instance/prototype chain of the “Function” object in the new window.


It’s all very confusing IMHO, but you lets say you have a set of scripts that constitute a little framework. You include it in one window and also in the other, then you create an object that has a prototype of “MyClass”… when you pass it from one window to the other, if you call “myNewObj instanceof MyClass” in both windows, you will get different results. In the child window has a whole different set of classes (even though to you, they are the same and have the same name, the browser treats them as different).


This is a big deal for classes that most assume are “built in”. Classes such as Array, Function, Object are technically new instances in every since window or frame. So an Array created in one window and passed to another will no longer return the correct response for “myArray instanceof Array” in the child window / frame.


I submitted a bugreport to Firefox and they gave me some good info on why it happens and what the spec says: Firefox Buzilla Link

Affected Browsers:

  • Internet Explorer 6
  • Internet Explorer 7
  • Internet Explorer 8 Beta
  • Firefox 3+ (for instanceof Function issue)
  • Safari 3+ (for instanceof Function issue)
  • Google Chrome (for instanceof Function issue)

Problem:

What I found is that when passing an object from one window to another like this:

  1. var obj = {"prop1":"Hello","prop2":"Whats Up","prop3":{"subProp1":"Hi","subProp2":"Yeah Yeah"}};
  2. obj["func1"] = function(){ alert("this is a test"); };
  3.  
  4. var w = window.open("new_window.php","newWindow");
  5.  
  6. Then Pass the Object to the Child Window.
  7. w.setObj(obj);
  8. Then print out the type of obj["func1"] in the parent…
  9. alert("In the parent: "+typeof obj["func1"]);
  10.  
  11. Then in the child:
  12. alert("In the child: "+typeof obj["func1"]);

For the object in the child window, in Internet Explorer “typeof obj["func1"]” returns “object” instead of “function”. In Firefox, Safari, etc it returns “function”.

Some possible solutions:

  • Check to see if the object has .call (a function which only functions have).
  • Convert the function to string then do a substring on the first 9 and compare it to the word “function”.
  • Don’t pass objects that contain functions across windows.
share
 

Permalink: Internet Explorer (IE) Cross-Window Javascript Object typeof Bug

Created:

« Back to Code Snippets

Leave a comment

You must be connected to post a comment.