No, it's not a bug (at least, not in the browser), and it's not just IE.
Each document the browser shows has its own global environment, including prototypes for the basic objects. They're each a blank slate. The Array
constructor in one document is not the same as the Array
constructor in another document, and those contructors don't share a common prototype
property; the environments are disconnected. That's why instanceof
doesn't work well in multi-document web applications.
Consider this example (live copy):
window.onload = function() {
document.getElementById('theButton').onclick = function() {
var wnd, start;
display("Adding property to <code>Array.prototype</code>");
Array.prototype.__foo = "bar";
display("Testing property locally, <code>[].__foo = " +
[].__foo +
"</code>");
display("Opening pop-up window");
wnd = window.open("http://jsbin.com/omopaw/3");
display("Waiting for window to load...");
start = new Date().getTime();
checkWindowLoad();
function checkWindowLoad() {
var a, b;
if (typeof wnd.getArray === "undefined") {
if (new Date().getTime() - start > 10000) {
display("Error, 10 seconds and the window hasn't loaded");
}
else {
setTimeout(checkWindowLoad, 10);
}
return;
}
display("Window loaded, getting array from it");
a = wnd.getArray();
display("<code>a</code> contents: " + a.join(", "));
display("<code>a.__foo = " + a.__foo + "</code>");
display("<code>a instanceof Array</code>? " +
(a instanceof Array));
display("<code>wnd.Array === Array</code>? " +
(wnd.Array === Array));
display("Creating <code>b</code>");
b = [3, 4, 5];
display("<code>b.__foo = " + b.__foo + "</code>");
display("Passing <code>b</code> to the popup, look there for the result.");
wnd.callback(b);
}
};
function display(msg) {
var p = document.createElement('p');
p.innerHTML = msg;
document.body.appendChild(p);
}
};
That opens a pop-up window and then retrieves an array from it. But the array we receive was constructed by a different Array
object than the one in our window, and so doesn't have the additions we made to our Array.prototype
. Then it creates an array instance that does have those additions and passes it to the pop-up, which sees the additions correctly (since the object continues to reference its original prototype):
Output in the main window:
Adding property to Array.prototype
Testing property locally, [].__foo = bar
Opening pop-up window
Waiting for window to load...
Window loaded, getting array from it
a
contents: 1, 2, 3
a.__foo = undefined
a instanceof Array
? false
wnd.Array === Array
? false
Creating b
b.__foo = bar
Passing b
to the popup, look there for the result.
...and in the pop-up:
I'm the popup.
Received x
: 3,4,5
x.__foo = bar
You'll see that output both on IE (I specifically tested IE9, but it works on IE7 and I'm sure others as well) and on other browsers.
The environments in the two different windows can talk to each other, but they don't have shared globals; the Array.prototype
in the parent window is not inherited by the child window in any way.
You've said in the comments than when you pass the array from the main window to the child window the additions "disappear." (There's nothing in your code showing you doing that.) We can see from the above that in fact, the object maintains its relationship with its prototype correct and does show the additions, so I suspect (with apologies) it's just an error in your code.