Problem
I'm trying to make a method that passes objects to a similar method in a popup window. I don't have control over the code in the target method, or the object passed in. The target method currently serialises the object, using JSON.stringify
where possible, or instanceof Array
.
The first problem with this is a bug in IE8 (see below). The second, and more fundamental, is that primitives are not the same across windows:
w = open("http://google.com")
w.Array == Array // returns false
Overriding on the popup any classes that might be passed in, and then restoring them after the call works, but it's really brittle and a maintenance headache.
Serialising the object into JSON and then parsing it in the context of the window hits the Firefox bug below.
I'm also a bit loathe to do a deep copy of the object or parse the JSON using new w.Object
, etc. because it doesn't feel like it should be that complicated.
Can anyone suggest a sensible way to deal with this, or should I just accept that objects can't be passed verbatim between windows?
IE bug
JSON.stringify
doesn't work across windows in IE8. If I pass an object to the popup, which attempts to serialise it, stringify returns undefined
. To see this problem, open the script console in IE8 and try:
w = open("http://google.com")
JSON.stringify(Object()) // returns "{}"
w.JSON.stringify(w.Object()) // returns "{}"
w.JSON.stringify(Object()) // returns "undefined" on IE8
JSON.stringify(w.Object()) // returns "undefined" on IE8
JSON.stringify([1, w.Object()]) // returns "[1,null]" on IE8
I tried working around this by setting w.JSON = JSON
, but as the last test shows, that breaks when you have objects from both windows.
Firefox bug
It seems that calling w.Object()
to create an object in Firefox in fact calls window.Object()
. The same bug is hit when calling w.JSON.parse
or w.eval
. To see this, open Firebug's console and try:
w = open("http://google.com")
new w.Object instanceof w.Object // returns true
w.Object() instanceof w.Object // returns false on Firefox 3.5
w.Object() instanceof Object // returns true on Firefox 3.5
w.Object.call(w) instanceof Object // returns true on Firefox 3.5
w.JSON.parse("{}") instanceof w.Object // returns false on Firefox 3.5
w.JSON.parse("{}") instanceof Object // returns true on Firefox 3.5
w.eval("[]") instanceof w.Array // returns false on Firefox 3.5
w.eval("[]") instanceof Array // returns true on Firefox 3.5
w.eval.call(w, "[]") instanceof Array // returns true on Firefox 3.5
The only workaround I can see is parsing the JSON string myself.